C言語なら俺に聞け 164

2025/11/12(水) 07:37:37.89ID:xTE5ywXt0
1文字づつ属性タグ付けてから好きな処理すればいい
2025/11/12(水) 09:44:34.01ID:9DKi0uHD0
>>118
標準関数というのが言語仕様 (規格) にある関数という意味ならディレクトリという概念すら無い。
ファイルを指し示す文字列は単に「ファイル名」としか書いておらず、どういった形式を持つかは規定されない。
ファイルシステムによって独特の概念がある場合もあるし、言語仕様で決めるような筋合いのものではないってことだと思う。

ホスト環境 (OS) のほうでなんらかの機能を提供している場合もあり、たとえば Windows だと shlwapi.h にある名前が Path で始まるやつはパス操作関係の API だ。
2025/11/12(水) 11:47:07.85ID:swftmftO0
DOS時代は文字コードをASCII、JIS/SJISしか知らなかったから
文字列操作は1字2バイトにする関数作って自分で処理してたな。
2025/11/12(水) 12:45:29.14ID:MQmntoo50
それで正しいよ

そもそも118の必要有ったっけ?と思ってfopen見たら、やっぱりフルパス受け付けるじゃん
Cでやるべき事と、やるべきでない(やる意味もなく、やっても無駄に嵌る)事を区別出来てないだけ
2025/11/12(水) 13:00:11.37ID:9DKi0uHD0
>>128
意味が分からない。
この場合にフルパスがどうこうというのはどのように関係してくる?
2025/11/12(水) 14:04:58.47ID:MQmntoo50
>>129
データ処理(fopen)したいのならディレクトリ区切り文字なんて気にする必要なく、そのままフルパス文字列を全部与えればいい。
だから118の処理をCで自前でやる事自体がナンセンス。
そのコードはその処理系が用意したfopen内に存在している。(か、そもそも必要ないか)

シンボリック/ハードリンク等のファイルシステム固有の件をおいておくとすれば、
ファイルシステムは、フルパスをプライマリキーとしたDBとして抽象化出来る。
そのプライマリキーの正規化や探索方法はDB(システム)側の事情であり、ユーザーが処理するべきではない。

つまり、ユーザー側は、入力されたパス/ファイル名文字列をそのままfopen等システム側に食わせるべきであって、
118の様に、自前で加工するべきではない。
勿論、お前の言うように、C自体にはディレクトリの概念すらないのだから、
Cでexplorerじみた物を作るにしても、「標準関数」ではなく、
例えばWindowsなら.NET等、環境が用意した関数群を使えば最初から何も問題が発生しない。

具体的に言った方が分かりやすいかな?
例えばunix環境だと//は/扱いになるはずだが、この辺も全部ご丁寧に実装していくつもりなのか?
(他に何が有るのかは知らんが、たぶんあるのだろうし)
或いはutfでは毎度言われてるMacの正規化がおかしい件
https://applech2.com/archives/20251106-time-machine-bug-still-unresolved-on-macos-26-1-tahoe.html
この辺も全部引き受けるつもりなのか?
こんな事やり出したら泥沼に嵌るのは間違いないので、118の設計思想にバグがある。
入力文字列そのままでファイルを探索出来ないのなら、エラーを返し、使用者に再入力させる実装の方が一般的に正しい。
(これを綺麗にやるのが例外システムだが、Cには例外がないので、
美しさに拘るなら、ファイルオープンまでは他言語でやって、実処理部分だけCのdllを呼ぶのがいいと思う。
Cしか書きたくないなら、一番近いのはVC++だろうよ)
2025/11/12(水) 14:04:58.47ID:MQmntoo50
>>129
データ処理(fopen)したいのならディレクトリ区切り文字なんて気にする必要なく、そのままフルパス文字列を全部与えればいい。
だから118の処理をCで自前でやる事自体がナンセンス。
そのコードはその処理系が用意したfopen内に存在している。(か、そもそも必要ないか)

シンボリック/ハードリンク等のファイルシステム固有の件をおいておくとすれば、
ファイルシステムは、フルパスをプライマリキーとしたDBとして抽象化出来る。
そのプライマリキーの正規化や探索方法はDB(システム)側の事情であり、ユーザーが処理するべきではない。

つまり、ユーザー側は、入力されたパス/ファイル名文字列をそのままfopen等システム側に食わせるべきであって、
118の様に、自前で加工するべきではない。
勿論、お前の言うように、C自体にはディレクトリの概念すらないのだから、
Cでexplorerじみた物を作るにしても、「標準関数」ではなく、
例えばWindowsなら.NET等、環境が用意した関数群を使えば最初から何も問題が発生しない。

具体的に言った方が分かりやすいかな?
例えばunix環境だと//は/扱いになるはずだが、この辺も全部ご丁寧に実装していくつもりなのか?
(他に何が有るのかは知らんが、たぶんあるのだろうし)
或いはutfでは毎度言われてるMacの正規化がおかしい件
https://applech2.com/archives/20251106-time-machine-bug-still-unresolved-on-macos-26-1-tahoe.html
この辺も全部引き受けるつもりなのか?
こんな事やり出したら泥沼に嵌るのは間違いないので、118の設計思想にバグがある。
入力文字列そのままでファイルを探索出来ないのなら、エラーを返し、使用者に再入力させる実装の方が一般的に正しい。
(これを綺麗にやるのが例外システムだが、Cには例外がないので、
美しさに拘るなら、ファイルオープンまでは他言語でやって、実処理部分だけCのdllを呼ぶのがいいと思う。
Cしか書きたくないなら、一番近いのはVC++だろうよ)
2025/11/12(水) 15:16:59.28ID:O9mfd+PO0
ディレクトリをぶんかつしたいって話にfopenとか何言ってんだ?とおもいました
2025/11/12(水) 15:17:06.90ID:9DKi0uHD0
>>130
たとえば指定されたファイルをアーカイブするときにパスからディレクトリ部分は取り除いて格納するだとか、文字列処理でパスを分解したいユースケースはごく普通にある。
アプリケーション作者が自前でやるのが困難なレベルの複雑な仕様なのであればそれは OS の機能かライブラリとして用意されるべき筋合いのことで、常に明示的にユーザが名前を与えるべきというのはナンセンスだ。
2025/11/12(水) 17:31:16.04ID:o8W1SstX0
パス名の分解で、0x5cを調べながらあれこれやったけどな。
2025/11/12(水) 23:03:06.47ID:MsLHjcva0
DOSであれこれパス操作するなら
まずスラッシュに正規化するのがいいんでは?
API(INT)はスラッシュでもそのまま通るし
2025/11/12(水) 23:53:18.57ID:MQmntoo50
>>133
それはお前が例外/抽象化/隠蔽/MVC等をまるで理解出来てない馬鹿だからだな。
まあ具体的に話をした方がいいようだから、そうしてみよう。

ただその前に、
> 常に明示的にユーザが名前を与えるべきというのはナンセンスだ。
「名前」とは何ぞ?
ユーザーが常に「フルパスを」与えろという意味なら、これもMVCを理解出来てない故の間違いだ。
そこはV(=UI)で補完するべき部分であって、
M(=本体の内部構造)には関わりない。(というより独立/分離している)

ついでに脱線しておくと、お前が典型的だが、Cの連中も不勉強が過ぎるとは思ってる。
馬鹿にされてるWeb系は、実際馬鹿しか居ないのも事実だが、
それでも回るように出来てる=馬鹿でも上手く行くシステムが構成されてて、これは学ぶ価値がある。
Cに引き籠もるのもどうぞ御自由にだが、
現在においてそれは、全然効率的でない、生産性の低いプログラミングに留まっている事を自覚しないと駄目だ。
そして、おそらくそういう連中に対して不満があって、
K&R警察と化したゴミクズ若害ゆとりZ>>98に俺は無駄に噛み付かれた訳だが、とんだとばっちりだ。
98は結局、よりよい回答を出しあう、上方向の競争には参戦せず、
より馬鹿にしあう、下方向の競争しかしなかったわけだから、ゴミクズであることは事実だが、
K&R警察が発生してしまうのは、お前らの問題でもある。
2025/11/12(水) 23:53:46.82ID:MQmntoo50
さらについでに言うと、string.hが割とゴミなのは広く言われてるが、
strtokについて問題を感じないのなら、間違いなく無知な馬鹿だ。
(俺は仕様を見た瞬間、え?こんなの許されるのか?と思った)
そしてそれで偉そうにしてるのなら、完全に老害だ。
(だから間髪入れずに叩いた>>119はまあ正しい)

strtokの問題点が分からなければ、使い方を書いたサイトがあちこちにあるからググればいい。
ただ、strtok関しては、使い方を解説するのではなく、使用禁止と明言すべきレベル。
初心者向けのつもりな各サイトなら尚更。
それらに書いてない事を追加すると、
俺はstrtokでは生産性が上がらない(=使う意味がない)のが駄目だと思っている。
strtokには必ずラッパが必要で、それは使い方サイトに大体出てるサンプルコードになるが、
どうしてもstrtokを使いたい局面では、
そのサンプルコードのstrtok部分を自前でループし、そのラッパ関数を公開した方がいい。
(strtokは関数内関数に留め、グローバルには公開しない)
こうすれば問題の半分は片づく。

ただそもそもCでディレクトリ分割する意味はなく、そのコードを作るのにかけた時間は全部無駄だ。
そのコードは既に他にもっといい出来なのがあるから、それを使うべき。
2025/11/12(水) 23:54:11.21ID:MQmntoo50
で、具体的な話をすると、
> 指定されたファイルをアーカイブするときにパスからディレクトリ部分は取り除いて格納するだとか
こんな事する必要ねえんだよ。
お前は具象レベルでしかプログラミング出来ない馬鹿だから、こうとしか考えられないだけ。
モノリシックにしか作れず、特定環境のファイルしか格納出来ないように、無駄に成るだけだろ。
ほぼ同じ手間であらゆる環境で使える物が出来るというのに。

具体的に言うと、この場合は、
M: 内部アーカイブ
V0: unix用UI
V1: Windows用UI
V2: Web用UI
とかに分ける。これでシステム間の引っ越しも余裕になる。
Mは、文字列(キー)→ファイル(値)が引けるDB/KVSなら何でもいい。
最もお手軽には、高速検索/アクセス機能が欲しければsqlite、
レストア出来ればいいだけならtarのようにグチャッとくっつけただけの物となる。
文字列(キー)には、アーカイブしたときのパスをそのまま記録する。
つまり、フルパスで有ればフルパスを、相対パスなら相対パスを指定する。
M-V間のインタフェースはこの文字列『全体』とする。
2025/11/12(水) 23:55:46.80ID:MQmntoo50
ここでおそらく、tarでアーカイブし、ディレクトリ名が重複するので端折る事を想定していると思われるが、
これは間違いだ。『ディレクトリ文字列』ではなく、単純に『文字列』を端折るだけでいい。
つまり、

ファイルシステム上:
./pathA/pathB/hoge.txt
./pathA/pathB/hogehoge.txt
./pathA/pathB/hogehogehoge.txt

はちみつ式tarアーカイブ:(ファイル名先頭に同一『ディレクトリ』かマークする=デリミタ文字を認識しないといけない)
(新)./pathA/pathB/hoge.txt
(同)hogehoge.txt
(同)hogehogehoge.txt

俺式tarアーカイブ:(直前レコードと『文字列が』頭から何文字同じかマークする=デリミタ文字を気にする必要ない)
(0)./pathA/pathB/hoge.txt
(18)hoge.txt
(22)hoge.txt

この例は偶々、俺式の方が圧縮出来るが、実際はこんな都合のいいファイル名並びはほとんど無い。
マークサイズが、はちみつ式はbool、俺式はint(またはshort/char)なので、実際にどちらが小さいかは場合によりけりだろう。
ただポイントは、俺式はファイルのデリミタ文字がMには関係ないところだ。
Mはただの倉庫であって、文字列→中身、が出来れば十分で、外部の仕様には一切依存しない、ということ。
(はちみつ式はデリミタが/であるunix仕様がMに癒着している。とはいえこれが問題になる事はまずないはずだが)
2025/11/12(水) 23:59:23.72ID:MQmntoo50
書けない?テスト
2025/11/13(木) 00:02:39.38ID:DM7iFpPI0
あと2投(44行)あるが、規制された?ので、しばらく後に投稿する
2025/11/13(木) 00:14:22.09ID:DM7iFpPI0
うむ、書けんな。まあ>>135は正しいが
143デフォルトの名無しさん (ワッチョイ 1f1c-5yZn)
垢版 |
2025/11/13(木) 07:23:44.03ID:BJCSCSAz0
staticオジサン居る?
カプセル化で、ダイレクトに非staticプロトタイプで関数コールしている?
あるいは、typedef struct { void (*polling)(bool *tick) } Txxx;のように構造体の関数ポインター経由でコーールしている?
InitializeコールしないでNULLポインターをコールすることもあるのが難。
構造体の方がアプリトップレベルのBinderで管理できるので良いように思えるが、いまいち悩むところ。
2025/11/13(木) 07:26:01.38ID:DM7iFpPI0
やはり書けないっぽい
行数制限か?
しばらくチマチマ試すが、駄目だったら諦めで
2025/11/13(木) 07:33:41.70ID:DM7iFpPI0
ここで先述の通り、M-Vインタフェースは文字列『全体』、つまり、
(18)hoge.txt から ./pathA/pathB/hogehoge.txt に戻す部分は、M側に持たせる。
2025/11/13(木) 07:37:32.03ID:DM7iFpPI0
んー、行数ではなく文字数制限か?
しかしバラバラだと読みにくすぎるので、また後日試すわ
2025/11/13(木) 07:59:27.63ID:DM7iFpPI0
Mangoで試して一部バラバラにすれば行けそうなので落とす。内容は以下と同一
https://agree.5ch.net/test/read.cgi/mango/1754986690/92-98
2025/11/13(木) 08:00:05.36ID:DM7iFpPI0
これにより、M側はsqliteと
2025/11/13(木) 08:00:31.21ID:DM7iFpPI0
交換可能になり、(DB/KVSの場合は上記ファイルシステム上の文字列そのままがキーになる)
2025/11/13(木) 08:00:57.42ID:DM7iFpPI0
アーカイブして戻すだけではなく、ライブファイルシステムとして使えるようになる。
これはsqlite公式でも言っている通り、
> https://sqlite.org/fasterthanfs.html
現在のブロックファイルシステムにおいては最低限4K食うので、小さいファイルが沢山の場合にはsqliteの方が効率がいいから。
(GUIが無いという話はあるが…まあexplorerでzip開けるあの感じがベストだとは思うが)

そしてVだが、順当に考えれば、キー(≒ファイル/パス/URI)については、
V0: unix用UI: 何もしない
V1: Windows用UI: \を/に変えて記録、/を\に変えて戻す(トークン分割ではなく、単なる文字置換)
V2: Web用UI: 何もしない
が妥当だろう。
各Vはそれぞれ使えない文字が異なるので、Mからその文字列が来たときにどう扱うかは各Vに任せる。
これでシステム間もあっさり解決だ。
ポイントは、保存対象が何であれ、Mの中身は同じで、M-Vインタフェースも同じ、ということ。
そして繰り返すが、トークン分割の必要はない。もっと初歩的な、文字置換だけで済む。
2025/11/13(木) 08:01:38.94ID:DM7iFpPI0
つまり構成としては、
M(sqlite): sqliteそのままでいい。
M(俺式tar): トークン分割は必要ない。
 (18)hoge.txt から ./pathA/pathB/hogehoge.txt に戻す文字列操作は、数えて、concatするだけ。
 \の検索も要らない。
であり、Mでの文字列操作は、必要ないか、極単純か、となる。

一方Vは、はっきり言ってCで作る意味がない。(高速/最軽量のCを生かす事は出来ない)
unixならシェルで作ればいいだけ。
sqliteはシェルからそのまま扱えるらしいので、
> sqlite3 データベースファイル名 < スクリプトファイル名
> https://iifx.dev/ja/articles/123001461/sqlite3スクリプトをコマンドラインで華麗に操る方法
find . -print の結果を適当にゴニョゴニョすればまあ行けそう。
Blobをどうやって作るのかは知らんが、多分手段はあるのだろう。(いい加減面倒になってきた)

Windowsでも、powershellで何とかなるんじゃね?駄目なら.NETでいいし。
どのみち、CでVを作る必要はない。
Cで作るのはMだけでよく、Mではなるべく文字列操作をしない、またはしなくて済むように設計する。
V部分は各環境の便利なものを使い、そこでファイル/文字列操作はやってしまう、という事。


というわけで、例外/抽象化/隠蔽/MVC等と言っておきながら、MVCしか説明出来てないが、面倒なのでこの辺で止める。
馬鹿に一々付き合ってても、ネットでは無限に馬鹿が沸くので、キリがない。
お前らが俺以上に手間を掛けたと分かる場合のみ相手するが、おそらくこれはないはず。
そしてこれ以上お前らが馬鹿こいても無視するのでよろしく。
無知のままで居るのもお前らの自由ではあるし、本当にキリがないので。
2025/11/13(木) 08:02:19.41ID:DM7iFpPI0
以上、終わり
2025/11/13(木) 15:04:26.13ID:bJCWdXAy0
>>136
支離滅裂で何ひとつ伝わっていないとだけ言っておく。
意味がわからないのでこれ以上は反応しない。
2025/11/13(木) 20:55:40.45ID:FrAYIMEk0
>>153
俺が新しく展開した話に対し、どう捉え、どう振る舞うかはお前の自由だ。
ただ、不十分であれ、俺はお前の質問/議論に対応しようとしたのだから、
お前も俺の質問、再掲するが以下には、同程度の対応をする義務はあると思うがな。
回答しないのなら、俺も今後はお前の質問>>129に対しての回答>>130すらも遠慮させて貰う。

>>133
ただその前に、
> 常に明示的にユーザが名前を与えるべきというのはナンセンスだ。
「名前」とは何ぞ?
2025/11/13(木) 22:45:21.40ID:bJCWdXAy0
>>143
言いたいことがよくわからん (非staticプロトタイプってなんや?) けど私なりに推測するとカプセル化の基本パターンや使い分けが知りたいってこと?
156デフォルトの名無しさん (ブーイモ MM4f-ACTV)
垢版 |
2025/11/14(金) 10:11:22.08ID:j5Ukc9dzM
「モバイルオーダー」悪用、1万円超の弁当代を58円で不正決済…23歳の無職男を容疑で逮捕

決済システムが脆弱すぎだろ?
よくこんな作り方で普及させたな?インド人か?
2025/11/14(金) 11:20:09.02ID:H7qd0VM/0
一万円の弁当か、食べてみたい
払う気はないけど
158デフォルトの名無しさん (ワッチョイ 1f2f-5yZn)
垢版 |
2025/11/15(土) 03:54:57.59ID:61X/lnkN0
あら C99で空宣言使えなくなった?

typedef enum {} PINSTATE;

typedef struct s_pinobj {
bool(*sequence)(struct s_pinobj * obj);
uint16_t tickcount; // 10ms ticking
PINSTATE state;
.
.
} TXXX;
などと使っていたんだけど、エラーになるようだ。
循環参照対策はどうするんだろ?
159デフォルトの名無しさん (ブーイモ MM4f-ACTV)
垢版 |
2025/11/15(土) 08:31:52.06ID:u+2daHyUM
客→クレジット会社鯖→決済情報→商店
の流れを

客→決済情報→商店
だとよ

つまりクレジット会社鯖でやってる業務をすべてなりすまししてるわけだ
鯖と商店とのやり取りもザルだったってこと
2025/11/15(土) 11:24:07.72ID:nRXHw60f0
>>158
空宣言というのは enum の列挙子がゼロ個ということを言ってるの?
enum が導入された C89 の時点で列挙子はひとつ以上が必要ということになっていて列挙子がゼロ個で良かった時代は無い。
(出来たとしたら処理系の拡張。)

そして enum の宣言は必ず列挙子のリストを必要としている。
struct のように { } を書かなければ不完全型として宣言されるというようなことはないから前方宣言で名前だけ書いておいて後で中身を定義するということも出来ない。
不完全型の列挙型というものは存在できないってことね。
2025/11/15(土) 11:40:24.78ID:YWAh8Gcip
>>159
普通は後にこんな流れが加わってるはず
商店→クレジット会社→決済情報コンペア→決済確認→商店→決済完了
162デフォルトの名無しさん (ワッチョイ 1fc9-ACTV)
垢版 |
2025/11/15(土) 14:39:56.35ID:mkkTDyMO0
>>161
そうなってないから決済が完了し、商品が届けられて犯罪成立しちゃってる

あとになって入金が合わずに発覚しただけだからなぁ
2025/11/15(土) 15:15:39.55ID:jhUkF2/k0
>>162
システム考えた奴、頭悪いのかなぁ?
暗号化とか過信したのかなぁ?
164デフォルトの名無しさん (ワッチョイ 1fc9-ACTV)
垢版 |
2025/11/15(土) 15:38:28.29ID:mkkTDyMO0
例え決済情報を盗まれてもさ、アクセス先がクレジット会社でもないとこからのやつを
なんで正規なものとして受け取るかね?
いろいろおかしい
2025/11/17(月) 21:52:49.67ID:WNaQVVCp0
C言語とは直接関係ない話題だが、
カード情報が盗まれてそのまま決済が
通過してしまった事件が過去にあった。
カード持ち主には返金されたが、
損害を誰が負担するかで揉めてた。
カード会社が持つケースもあったが、
テナント企業が弱いと、涙を流すケースもあった。
2025/11/17(月) 21:56:21.37ID:ktJ33fIe0
直接どころかまったく無関係で草
2025/11/18(火) 00:14:16.54ID:Ie2Q8O000
Eコマースサイト作る上では必要な知識だからな
全く無関係って訳ではない
168デフォルトの名無しさん (ワッチョイ 259c-L2M8)
垢版 |
2025/11/18(火) 00:20:37.35ID:3HXouIV30
Cで作るの?
169デフォルトの名無しさん (ワッチョイ 5202-F/8Y)
垢版 |
2025/11/18(火) 16:36:11.76ID:d9hs+rsN0
cのcgiだって可能だしあってもいいだろ(?)
170デフォルトの名無しさん (アウアウウー Sa85-H7iN)
垢版 |
2025/11/18(火) 23:45:44.92ID:+AochNn2a
windows で
setlocale(LC_ALL, "ja-JP.UTF8"); とか
setlocale(LC_CTYPE, "ja-JP.UTF8"); とか
プログラムの先頭で設定しても無駄?
console は chcp 65001 してる
fopen() のファイル名に UTF8 で渡したいんだが
出来れば readdir() も UTF8 で取得したいのよ
2025/11/19(水) 07:24:28.12ID:1qR7LTyn0
ソースコードがSJISなら無駄
2025/11/19(水) 10:44:13.50ID:sa05/K8dd
opendir and readdir themselves work on bytes. They do not perform and reencoding.
Some filesystem drivers may impose contraints on the byte sequences.
I would expect the form returned by readdir to work when passed to opendir.
I'd like to know how you were able to find out that opendir and readdir do not perform any reencoding? 
You can trace it through the C library source and the kernel code.
If you run strace ls, you can directly start from the kernel entry point: the open syscall.
The generic filesystem support code passes all bytes other than null and / along unmodified.
It's only some filesystem drivers that transforms file names.
2025/11/19(水) 11:29:22.16ID:MnCaLNwG0
>>170
普通の入出力はテキストモードとバイナリモードがあって、ロケールの設定がテキストモードの振る舞いに影響するんだけど……
Windows の場合はテキストモード・バイナリモード・ユニコードモードに分かれていて _setmode でユニコードモードに設定する必要がある。
しかしユニコードモードの設定はワイド入出力系関数 (wprintf など) にしか影響を及ぼさない。

そんでその辺の設定をしても、入出力の内容に関してであってファイル名を UTF-8 で渡すのはたぶん駄目なはず。 (確認はしてない。 すまぬ。)
ファイル名はワイド文字 (UTF-16) に変換してから _wfopen で開くのが正当な方法だと思う。

Windows に readdir は無いので FindFirstFileW, FindNextFileW を使うのが普通の方法。

だいぶん前に調べたときは msvcrt と ucrt でちょっと振る舞いが違ったような記憶があるのでそこらにも注意が必要。
ucrt は色々と大きく改良されているみたいなのでひょっとするともっとモダンな方法があるかもしれない。
2025/11/19(水) 12:12:33.50ID:DtAPl5720
UTF16は廃止してほしい
175デフォルトの名無しさん (ワッチョイ ae25-Lseg)
垢版 |
2025/11/19(水) 13:55:46.72ID:95cnfr9u0
ANSI C以前のC処理系で、frexp()の第2引数が、intではなくdoubleへのポインタになってるやつってありましたっけ?
レスを投稿する

5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況