1 名前:名無しさん@お腹いっぱい。 [2005/09/22(木) 20:29:34 ] UNIXおよびUNIX clone環境一般のプログラミングに関する質問スレッド 過去スレ(プログラム技術板) Part6 pc8.2ch.net/test/read.cgi/tech/1116908090/ Part5 pc8.2ch.net/test/read.cgi/tech/1105723117/ Part4 pc5.2ch.net/test/read.cgi/tech/1095843584/ Part3 pc5.2ch.net/test/read.cgi/tech/1085930894/ Part2 pc5.2ch.net/test/read.cgi/tech/1055110889/ Part1 pc2.2ch.net/tech/kako/992/992057422.html Part3ミラー makimo.to/2ch/pc5_tech/1085/1085930894.html Part2ミラー makimo.to/2ch/pc5_tech/1055/1055110889.html 関連スレ Cygwin使っている人いますか? その14 (UNIX板) pc8.2ch.net/test/read.cgi/unix/1107587275/ Cygwin使っている人いますか? 3 (Windows板) pc8.2ch.net/test/read.cgi/win/1090131123/ 関連板 Linux板 pc8.2ch.net/linux/ プログラム技術板 pc8.2ch.net/tech/
401 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 10:44:48 ] >>395 仕様としてそう決まっていようが、現実はそうじゃない。 $ echo 'main(){}' | gcc -xc -; ./a.out; echo $? 148 $ echo 'main(){}' | gcc -xc -; ./a.out; echo $? 84 $ echo 'main(){}' | gcc -xc -; ./a.out; echo $? 101 毎回未定義。
402 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 10:44:57 ] >>400 つかえましたよ。 int main() { puts("xxx"); } つーか、linkとごっちゃになってね。
403 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 10:49:17 ] >>402 >>395 に言ってくれ。
404 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 10:51:45 ] >>401 ↓これじゃない int main() return 0; の話だろ ↓こっちは省略禁止 int main()
405 名前:400 mailto:sage [2009/03/01(日) 10:57:24 ] ああ、ごめん。 >>395 は論外としてputs云々が気になったので.... でだ。 ばかも ん。 昔のcompilerはなぁ、昔のcompilerはなぁ、 まともなwarning吐かないので、lint使ってたんだぞぉ。
406 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 10:57:31 ] >>400 だから、話の流れ的に「C++では」なの(>>395 >>394 >>392 )。 C++では「宣言の無い関数は呼び出せない」の。 某コンパイラを除いてね。
407 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:00:40 ] >>401 あなたが省略してるのは「戻り値」ではなく「戻り値の型」。 話の流れとは全然関係ないから。 CでもC++でも f() { return 0; } という「戻り値の型の省略」は完全に合法ですから。 もちろんintと仮定されます。 そして、何もreturnしない場合、まっとうなコンパイラなら警告が出ます。
408 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:11:43 ] >>404 >>407 int付けても同じだよw そこが論点じゃないしww $ echo 'int main(){}' | gcc -xc -; ./a.out; echo $? 41 $ echo 'int main(){}' | gcc -xc -; ./a.out; echo $? 116 $ echo 'int main(){}' | gcc -xc -; ./a.out; echo $? 32 毎回未定義。
409 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:12:13 ] >>395 がCの話だと思ってる人って わざわざ「printfが言語仕様に含まれる」と触れてる事を疑問に思わないのかな。 少し前に>>389 があるのに。
410 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:19:51 ] >>408 >>406 や>>393 を無視して、何故わざわざ「省略可能なことが言語仕様で保証されていないC89」でコンパイルするわけ?
411 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:25:23 ] 「C++では言語仕様で保証されている、だからC++のコードだ」という話(それが妥当かはともかく)なのに わざわざ「言語仕様で保証されてない言語(C89)」での結果を何度も貼りつけて何がしたいのかな。
412 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:26:39 ] あ、違った。 「言語仕様で「不定」となることが決まっている言語」だな。
413 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:30:14 ] >>404 の書き方では、「intさえ付ければ戻り値は固定される」と 言ってるように見える。 >>408 はそれに対する反論かと。
414 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:32:03 ] >>404 で言ってるのは >>401 に対して仕様で省略が認められてるのはreturnの方だけだよということだろう
415 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:33:39 ] >>414 でも結局省略したら値が不定んなったんだから省略できないじゃんw
416 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:36:35 ] >>415 だからC99規格対応なら、省略できて C89規格ではそうではないって話だろ
417 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:39:25 ] >>416 結局省略できないじゃんw
418 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:45:48 ] 省略できる言語の話をしてるんだろ? 何で別の言語の話をする?
419 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:48:28 ] 省略できるって主張してる奴は、 「仕様上は省略できるはずです」って言って、 不定値を返すままのソフトを納品すればいいさ。
420 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:56:21 ] >>419 実装がとにかく正しいとか言って、コンパイラ依存のプログラムでも作ってろ
421 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 11:59:15 ] だったらせめて -xc をやめて -xc++ や -std=c99 をつけた結果を貼れよ。 C89で保証されてないことなんか、知らない奴殆ど居ないんだから。 >>376 からの流れなのに>>380 がC++の話じゃないと思い込むバカは居るかもしれないけど。
422 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 12:02:08 ] >>419 どこに、「C89で省略できる」って主張してる奴がいる? あ、いるのかな。 戻り値が保証されてるとは誰も書いていない、ってだけで。
423 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/01(日) 12:12:12 ] ×戻り値が保証されてるとは誰も書いていない ○戻り値が保証されると脳内で勝手に決め付けて特定の実装の結果を張り続けるバカもいる
424 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/02(月) 10:17:57 ] linuxだとsearch.hのハッシュがやけに遅いのでGhashTableのが性能いらしいんだけど FreeBSDの場合ハッシュの実装をするのにGhashTableとsearch.hと どっちのがおすすめ?
425 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/02(月) 12:38:43 ] ほとんどの人には不要だと思うけど、一応張っとく。 C++とC98は、main関数は暗黙のreturn 0。C89とその前はそうではなかった。 $ echo 'int main(){}' | gcc -std=c99 -xc - && ./a.out; echo $? 0 $ echo 'main(){}' | gcc -std=c99 -xc - && ./a.out; echo $? <stdin>:1: 警告: return type defaults to ‘int’ 0 $ echo 'int main(){}' | gcc -Wall -std=c++98 -xc++ - && ./a.out; echo $? 0 $ echo 'main(){}' | gcc -Wall -std=c++98 -xc++ - && ./a.out; echo $? <stdin>:1: 警告: ISO C++ forbids declaration of ‘main’ with no type 0 # 禁止されてるけどエラーにならない $ echo 'int main(){}' | gcc -Wall -std=c89 -xc - && ./a.out; echo $? <stdin>: In function ‘main’: <stdin>:1: 警告: control reaches end of non-void function 196
426 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/02(月) 12:48:53 ] >>424 基本どっちもクヌース本のアルゴリズム。
427 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/02(月) 12:52:43 ] C98という新規格まで登場したか。
428 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/02(月) 13:32:40 ] >>425 おまえがC++とCごっちゃになってどうする
429 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/03(火) 09:27:07 ] Cのコード中でディレクトリの内容を比較するのはどうしたらいいか悩んでいます。 動作的には "diff -r dirA dirB" を実行した場合の結果と同じ処理をしたいのですが、 毎回 diff コマンドを呼ぶオーバーヘッドを避け、出来ればCのコードで実現したいと 思ってます。どうすべきでしょう? 1. UNIX の API にこの目的にふさわしいものがあり(何という名前?)、それを使う 2. 違うファイルかディレクトリに遭遇するまで地道に両者のディレクトリを辿るような コードを自分で書く 3. diff のソースコードを入手し、自分のプログラムにリンクして使う 4. その他
430 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/03(火) 09:57:03 ] お前の書くコードがdiffよりオーバーヘッドが少ないわけがない。
431 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/03(火) 10:09:27 ] >>429 普通のdiffコマンドは高速でないアルゴリズム( O(ND) )を使ってるから、 gitとかpythonのライブラリに使われてるやつのが速い ってわけで、速度を追い求めるなら差分取得のアルゴリズムについて調べてがんばれ
432 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/03(火) 10:12:30 ] いや高速でないってこたないんですよ、それより速いのがあるだけで
433 名前:429 mailto:sage [2009/03/03(火) 10:29:38 ] あー書き方が悪かったかな。 もし diff ということで LCS とかそこらへんに脊髄反射されてたらごめんなさい。 自分が知りたいのは dirA と dirB の内容が違うか同じかだけなんです。 この場合むしろディレクトリの階層に効率よくアクセスできることが重要なんじゃないかと 思ったんですが、違います? fts とかですかね? それにファイルを処理するようなソフトならありがちな処理のような気がするので、 どこかに適切なコードのサンプルがあればと思って...
434 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/03(火) 10:37:16 ] >>433 > 自分が知りたいのは dirA と dirB の内容が違うか同じかだけなんです。 内容の比較は必要か タイムスタンプの比較だけでいいか 同じファイル名が存在するだけでいいのか rsync --dry-runの出力結果を使うとか。
435 名前:429 mailto:sage [2009/03/03(火) 10:50:52 ] >>434 「同じ」とはディレクトリ構造が同じで、その中に存在するファイルの名前&内容が同じ という積もりです。 タイムスタンプは比較しません。 >rsync --dry-runの出力結果を使うとか。 はい、確かにそれも速そうですが、自分のプログラムだと比較的浅いディレクトリに 対してそれを何度も呼ぶことになりそうなので、C の何かの API で書いた方がいいのか なあと。 ある意味 rsync みたいなプログラムなんですが、syncするときにいろいろカスタムな ロジックを入れたいので、コードを書いているといいますか....
436 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/03(火) 11:32:23 ] 内容比較がcmp -sレベルでいいなら、 readdir/lstatで自分で書けばいいんじゃない? 質問せずに書けば、今頃書き終わっている頃かと。
437 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/03(火) 13:31:30 ] ファイルとディレクトリの equality は適当に定義出来 るとして、↓みたいになるかな。 for (File src = each of srcDir) { File dst = dstDir.Find(src); if (dst == null) { // src にしかない } else if (src != dst) { // 違う } } for (File dst = rest of dstDir) { // dst にしかない } each of …は都度 readdir して、Find は保持してるプー ルから探して、無ければ見つかるまで readdir、してプー ルに入れていく感じ。見つかったらプールから削除して おいて rest of …でそれを得る。
438 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/03(火) 14:07:34 ] 両方コレクションにいれて、ソートして、 先頭二つ、計四つを比較しながら取り出せばいい。 四つになるのはどちらが欠けているかわからないから。 どれも違う場合、四つの中で小さいの二つを捨てればいい。 AB AB AB BC BC AB - AB CD AC BD
439 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/03(火) 14:16:00 ] >>438 ファイル/ディレクトリの equality と同様に順序付け も定義出来るなら(ソートするからには出来るはずだ)、 先読みする必要はない。マージソートの要領だ。
440 名前:名無しさん@お腹いっぱい。 [2009/03/12(木) 19:41:22 ] dirp=opendir("."); printf("1 :%d;\n",telldir(dirp)); printf("2 :%d;\n",telldir(dirp)); printf("3 :%d;\n",telldir(dirp)); closedir(dirp); とすると返す値は1,2,3とどんどんインクリメントしていくだけだし seekdirは無反応rewinddirは巻き戻すばかりかtelldirをひとつ進めるだけ readdirとかはちゃんとできているんだけれど 何か呪文とかいるのかダメダメな関数なのか情報please
441 名前:名無しさん@お腹いっぱい。 [2009/03/12(木) 19:51:28 ] >>440 OSはFreeBSDです。
442 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/12(木) 20:15:55 ] たぶん実装がおかしいんだろう。MacOS Xも同様らしい。 ttp://idm.s9.xrea.com/ratio/2007/09/10/000673.html dirent読むのにtelldirやseekdir使うようなやつはいないから放置されてると想像。
443 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/12(木) 20:24:17 ] 追加。このへん関係あるかも。 ttp://www.freebsd.org/cgi/query-pr.cgi?pr=bin/121656
444 名前:名無しさん@お腹いっぱい。 [2009/03/12(木) 20:32:49 ] >>440 です。rewinddirの記述は間違っていました。 rewinddirとreaddirだけが使えます。 で調べたらscandirというのがありました。 mallocしてくれて配列に入れて関数指定すればsortもしてくれるようなので コールバックもsort関数に入れます。 >>435 もscandir+lstatでいいのでは? しかしひどすぎるなtelldir+seekdir ファイルの多いディレクトリーでちょろちょろよむもん作りたかったんだけど 一気読みが基本ですか?
445 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/12(木) 20:38:50 ] とりあえずコールバック抜きのアルファソートやってみた。 c = scandir(dirname, &namelist, NULL, alphasort); if(c == -1) { puts("not opendir"); return(1); } printf ("%d\n", c); for (i = 0; i < c; ++i) { printf ("%s\n", namelist[i]->d_name); free(namelist[i]); } free(namelist); opendirの苦労は一体....orz
446 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/12(木) 20:40:17 ] >>435 opendir -> ディレクトリをファイルとして開く readdir -> ディレクトリのエントリを一つ読み込む(ポインタ一個進む) seekdir -> ディレクトリのエントリを x 番目にセットする telldir -> 今いるエントリ位置を報告する を組み合わせて, 双方のエントリを比較して 1. 対象物の inode が同じなら処理スキップ 2. 対象物が ディレクトリなら, 自分自身を再帰的に呼び出す 3. 対象物がファイルなら中身を比較 すればええんちゃう?
447 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/12(木) 20:46:16 ] 既に読んだエントリに戻って読み直すシチュエーションがわからん。 仮にtelldir/seekdirの動作がまともでも、 いちいち物理的にディレクトリ読みに行くような実装だったりしたら、 遅いし最中に誰かがいじらんとも限らんし、いいことなしでは? キャッシュしてるんだとすれば一気読みと何も変わらんし。 というわけで、telldir/seekdirは価値なしなんじゃないかと。
448 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/12(木) 21:00:32 ] >>447 再帰して必要物がなくって、バックトラックするときに 変わってしまった状態を元に戻すために必要 recur_dir(... here = telldir(... if (このエントリが dir && 比較対象と違う) if (recur_dir(...) == succeed) return なんとか ここに戻ってきた場合何がどうなってるか保証できない seekdir(here) 続きの処理
449 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/12(木) 21:56:26 ] 何がどうなってるか保証できない状態なら telldirしたところにseekdirしても保証できないだろう
450 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/03/15(日) 11:44:20 ] ストリームとしてファイルリストをチェックしていくならseekとかは必須だと思うけれど telldirもseekdirも機能しないんだから必要でも存在しない事実をどうする。 一旦readdirだかscandirでざっくりと読み込んで それに対して操作するしか方法が無いのが現実。 バックアップとかで完全一致を目指す場合 「ほぼあっている」前提ならば結局ファイル自体の完全マッチをするしかないと思うが 事前にMD5とかSHA1とかとったリストをディレクトリーに入れとけばそれで済む気はする。