【ISO/ANSI/JIS】 C言語なら俺に聞け! Part 131 at TECH
[2ch|▼Menu]
[前50を表示]
450:デフォルトの名無しさん
07/05/01 17:51:27
stdioのFILE系で読み書きを同時にするのはトラブルの元だって
たしかrubyの人が言ってた気がする。

451:デフォルトの名無しさん
07/05/01 18:00:03
宿題の答えとしては条件に合わない方法

unsinged long c = a + b;
if(c < a) {
 puts("Overflow");
} else {
 puts("(a+b) OK");
}

∵)
オーバーフローしたとすると、
c = a + b - m (m = 0x100000000)
c >= a だと仮定すると b >= m となるが、b < m なので矛盾する。
従って、オーバーフローした場合は必ず c < a となる。

逆に、オーバーフローしていない場合に
必ず c >= a になるのは自明。

∴ c < a ならばオーバーフローしている。

452:デフォルトの名無しさん
07/05/01 18:06:40
>>449
分岐は基本的にコストが高いから
分岐が少ない方が速くなる可能性はあるけど、
どのくらい速くなるかは
環境と実行条件によるとしか言えない。
だから、よく使われると想定する環境下で実測するしかない。

ただ、よほどじゃないと問題にならない程度の差しかないと思うけどね。今の時代。
数兆周のループの中に入ってるとかでもない限り。

453:デフォルトの名無しさん
07/05/01 18:32:01
a > 0xFFFFFFFF - b
ではいかんか?

454:デフォルトの名無しさん
07/05/01 18:47:24
氏ね

455:デフォルトの名無しさん
07/05/01 19:25:10
>>445
Hacker's Delightの2-12でも読めば?

456:デフォルトの名無しさん
07/05/01 20:51:40
リモートの機器から日、時、分、秒を取得して、
ローカルの日時から、年月を補ってtime_t型通算病
(所謂UNIXタイム)を求めたいのだけど・・

単純にtime, localtime, mktimeで作ると、月替わりタイミングでバグるよね。
スマートなやり方があった気がするが・・思い出せない、おながいします。

※リモートとの時刻誤差は数分以内程度を想定してます。



457:デフォルトの名無しさん
07/05/01 20:55:26
日が違ってる場合に年月の補正をすればいいんじゃない?

458:デフォルトの名無しさん
07/05/01 23:47:23
C言語の問題じゃねー気がするが
日が取得できるのならそれをつき合わせて補正でイナフ

459:デフォルトの名無しさん
07/05/02 00:24:31
年が今年なら、年月日だけあわせて0時の通産を求めて時分秒足したら

460:デフォルトの名無しさん
07/05/02 01:02:14
>>451
このスレ的には加算を禁じる理由は何もないからいいんじゃね

461:デフォルトの名無しさん
07/05/02 01:23:14
>>457-459
サンクス、思い出した。言語は関係ないな、こんなイメージで、ぶちこんどいた。

time_t now = time(0);
struct tm local = *localtime(&now);
time_t adjust = (local.tm_mday - remote->tm_mday) * (24 * 60 * 60);
if (adjust > issenwokoeta) {
  throw new AdjustOverflowException();
}
local.tm_mday = remote->tm_mday;
local.tm_hour = remote->tm_hour;
local.tm_min = remote->tm_min;
local.tm_sec = remote->tm_sec;
return mktime(&local) + adjust;



462:444 のものです。
07/05/02 02:04:03
あるプログラムから別のプログラムから立ち上げて、
その標準入出力を掴むプログラムを作っていたものです。

その呼ばれたプログラムのstdin,stdoutを呼び出し元プログラムで制御するまでに一立ったのですが。
仮にsshやftpを立ち上げてみると、ログインパスワード入力時の
「Password:」 の表示が標準出力じゃないみたいで、
呼び出し元プログラムを通さず、画面に出てきてしまいます。

一体何故でしょうか?

463:462訂正
07/05/02 02:04:43
>あるプログラムから別のプログラムから立ち上げて、

あるプログラムから別のプログラムを立ち上げて、


464:デフォルトの名無しさん
07/05/02 02:41:30
>>463
スレ違い。

465:デフォルトの名無しさん
07/05/02 03:03:04
んじゃ別のところで;^^)

466:デフォルトの名無しさん
07/05/02 04:58:46
つ【stderr】

467:デフォルトの名無しさん
07/05/02 09:34:10
パスワード系はエコーバックもあれしてるからなあ

468:デフォルトの名無しさん
07/05/02 11:25:37
つ/dev/tty

469:デフォルトの名無しさん
07/05/03 04:12:22
話ぶった切って悪いんですがILP64環境で4バイト長の整数を使いたいときってどうなるの?

470:デフォルトの名無しさん
07/05/03 04:23:57
C99 ならこれが使えるんじゃないかと思うけど、どうだろう?
URLリンク(seclan.dll.jp)

471:デフォルトの名無しさん
07/05/09 11:36:43
ヘッダにコードを書いてはいけないと聞いたのですが
何かあるのでしょうか?
別に書いても動きますよね?

472:デフォルトの名無しさん
07/05/09 11:42:37
動く事は動くが再利用性やコードの見通しが悪くなるからあんまり書かない方がいい

473:デフォルトの名無しさん
07/05/09 11:55:36
>>471
規格の 6.9 External definitions で、一つの関数または変数に対する定義は
プログラム全体で一つ以下(使われなければ無くてもいい)と制限されている。
ただし inline 関数や初期化子の無い外部変数定義は例外。

ヘッダは複数のコンパイル単位に取り込まれるので、うかつに関数や変数の
定義を置くとプログラム全体としては同じ名前に対する定義を複数持ってしまう
ことになり、未定義動作となる。

現行の一般的な処理系では、この規則に反するほとんどの場合がリンク時に
「重複した定義」などのエラーとして報告される。

474:デフォルトの名無しさん
07/05/09 12:03:53
>>472 473
なるほど、わかりました。
ありがとうございます。

475:デフォルトの名無しさん
07/05/09 13:41:50
3次元配列を使ってプログラムを組んだんですが、これをポインタを使ったプログラムに書き換えたいです。
簡単な方法があれば教えて欲しいです。
いまいちポインタが分かってないもんで、よろしくお願いします。
3次元配列は、2000*2000*2000の配列です。

476:デフォルトの名無しさん
07/05/09 14:03:38
>>475
配列とポインタって中でやることはほとんど同じだから、
書き換えたってたいして意味無い(動かないものが動くようになったりしない)よ?

> 3次元配列は、2000*2000*2000の配列です。
これ、一般人が買うようなPCだとオンメモリでは扱えない大きさだよ?
(わかってるならいいんだけど)

477:デフォルトの名無しさん
07/05/09 14:22:57
>>476

ありがとうございます。やっぱり動作が軽くなったりはしないですよね・・・


478:デフォルトの名無しさん
07/05/09 14:28:48
何十ギガという単位で実メモリがあれば速くなるんじゃないかな。


479:デフォルトの名無しさん
07/05/09 14:47:12
今FDにはいっている会員IDとPCの中にあるDATファイルの会員IDを照らし合わせて、同じ会員IDの名前だけとりだすというプログラムをつくっているんですがどなたか優しいできる方プログラムをのせていただけませんか?おねがいします!

480:デフォルトの名無しさん
07/05/09 14:50:45
まずは両方のデータをアップしなさいな。
データのフォーマットがわかないと作れないじゃん。

481:デフォルトの名無しさん
07/05/09 14:53:31
訂正:わかないと→わからないと

482:デフォルトの名無しさん
07/05/09 14:55:28
データとは会員IDのナンバーとかですか?ほんと初心者ですいません。

483:デフォルトの名無しさん
07/05/09 15:26:41
FDの中のデータは会員IDのみになっていて、1001がはいっています。PCのDATファイルには会員ID、名前、生年月日、住所の順に
1001 田中 19840908 千葉県
1002 高橋 19841203 埼玉県
1003 吉田 19840405 山形県
1004 佐藤 19841112 沖縄県
がはいっています。この2つを照らし合わせて1001のIDの田中だけ表示させたいというプログラムです。やさしいかた教えてください!お願いします!

484:デフォルトの名無しさん
07/05/09 15:35:58
>1001 田中 19840908 千葉県
「1001」と「田中」の間には何があるの?
半角スペース?
他の項目の区切りも同じ?

485:デフォルトの名無しさん
07/05/09 15:41:40
区切りは全部タブです!よろしくお願いします!

486:デフォルトの名無しさん
07/05/09 16:00:39
>>480 >>484
丸投げするような莫迦の相手をするな。

487:デフォルトの名無しさん
07/05/09 16:07:23
何日までに作ってほしい?

488:デフォルトの名無しさん
07/05/09 16:16:07
早ければ早いほどうれしいですが忙しいなら無理には大丈夫です。今週いっぱいにはつくりたい予定ですが。丸投げですいません。よろしくお願いします。

489:デフォルトの名無しさん
07/05/09 16:21:33
代金は銀行振り込みでいい?

490:デフォルトの名無しさん
07/05/09 16:28:26
#include <stdio.h>

const int BUFFER_SIZE = 100;
int main()
{
int y,m,d,days,n;
char buf[BUFFER_SIZE],c;
printf("年月日を入力してください\n");
while(true){
fgets(buf,BUFFER_SIZE,stdin);
n=sscanf(buf,"%d%d%d%c",&y,&m,&d,&c,);
if(n==3){
break;
}
else if(n==-1){
continue;
}
else{
printf("error\n");
return 0;
}
}


年月日を入力して曜日を求めるプログラムの一部なんですが、
fgets(buf,BUFFER_SIZE,stdin);
n=sscanf(buf,"%d%d%d%c",&y,&m,&d,&c,); の部分はどういう処理になるんでしょうか?nに整数が入るのがイマイチわかりません

491:デフォルトの名無しさん
07/05/09 16:44:15
ユーザがどういう入力をすると想定してるの?
もしかして"20070509"(YYYYMMDD)とか?

492:490
07/05/09 17:05:15
そうです。2007 5 9 って半角スペースで区切ると曜日が表示されます。
2007 5 9みたいに入力してなぜnが3とか-1とかになるんですか?

493:デフォルトの名無しさん
07/05/09 17:10:27
-1 ではなく EOF と書け。

494:デフォルトの名無しさん
07/05/09 17:22:59
>n=sscanf(buf,"%d%d%d%c",&y,&m,&d,&c,);
この%cは何を得ようとしてるの?

495:デフォルトの名無しさん
07/05/09 17:27:22
標準関数のリターン値の意味を質問しているのか?

ヘ ル プ 読 め。

manとかMSDNとかググるとか、ヘルプ読めない環境でプログラミングなんて無茶だから。

496:デフォルトの名無しさん
07/05/09 18:04:25
>>483
#include <stdio.h>

int main(void)
{
 system("grep -f fddata.dat pcdata.dat");
 return 0;
}


497:490
07/05/09 18:14:30
簡単に書き直したらうまく出来ました。
ありがとうございました

498:デフォルトの名無しさん
07/05/09 22:44:15
WindowsでもLinuxでもいいんだけど共有メモリ使う時に
構造体にキャストして使う方法とわざわざmemcpyで各要素ごとにコピーする方法が
等価だって言い張る人にどうやって違うんだよって説明すればいいですか?

相手は37歳のシナです。

499:デフォルトの名無しさん
07/05/09 22:56:06
>>498
比較用のコードを書いて、ベンチマークの結果をみせてやるとか。

500:デフォルトの名無しさん
07/05/09 22:57:49
>>498
そのシナさんはキャストでもコピーが作成されると思ってんの?
だとしたら、キャストの場合はアドレスが変わってないことを
見せてあげればいいんじゃない?

501:デフォルトの名無しさん
07/05/09 22:58:49
>>498
まず >>1 を読み直せ。それでも相談を続けるなら2つの方法に
対応するコードと、双方の主張を理由をつけて挙げてくれ。

502:デフォルトの名無しさん
07/05/09 22:58:50
>>499
それが、そうやって今しがたみせてやりましたが今度は
このような書き方は一般的じゃないとかいって怒り出して机をめちゃめちゃに
して帰りました。おまえの低能ぶりには呆れるとか捨て台詞を吐いて行ってしまいました。

正直な話、共有メモリの一番うまい使いかたってOpenMPとか見たいに自作のデータ構造を
そのまま共有メモリで共有できる形が理想なのにそれを言っても解かってもらえないのだろうか。

503:デフォルトの名無しさん
07/05/09 23:02:04
よそでやれ

504:デフォルトの名無しさん
07/05/09 23:10:58
Cの話じゃないよね
そいつの人格か理解力の問題か
そういう人とのコミュニケーションの取り方の問題だよね

505:デフォルトの名無しさん
07/05/09 23:12:08
>>502
シナさんがこんな時間まで残業付き合ってくれてたんなら少しは大目に見てやれ。

506:デフォルトの名無しさん
07/05/10 00:32:14
マ板でやれ

507:デフォルトの名無しさん
07/05/10 11:03:51
483ですがどなたか本当におねがいします。新社会人でこまっています。やさしい方おねがいします。

508:デフォルトの名無しさん
07/05/10 11:12:27
Excel でも使えば?

509:デフォルトの名無しさん
07/05/10 11:14:59
>>483
Cじゃないとだめ?
C#とかJavaは?

510:デフォルトの名無しさん
07/05/10 11:17:50
>>507
>>1 を100回音読後、首吊って詫びろ阿呆。

511:デフォルトの名無しさん
07/05/10 11:33:06
>507
上司に「できません」って言え

512:デフォルトの名無しさん
07/05/10 14:37:05
>>507
仕事なのか? だったらコマンドラインで grep 使えよ。
わざわざ作れもしないCプログラムで仕事を遅らせるのはアホ。


513:デフォルトの名無しさん
07/05/10 15:00:16
>>507
もしやそれは練習課題?

514:デフォルトの名無しさん
07/05/10 17:29:15
上にもあるように、scanfつかえ

515:デフォルトの名無しさん
07/05/10 18:10:54
ごめんなさい。でも真剣に困ってるし助けてほしいんです。よろしくお願いします。

516:デフォルトの名無しさん
07/05/10 18:12:27
だからscanfつかえよ

517:デフォルトの名無しさん
07/05/10 18:13:24
帰れ

518:デフォルトの名無しさん
07/05/10 18:13:55
常識知らずにかける情けは無い

519:デフォルトの名無しさん
07/05/10 18:20:37
スレ違い

520:デフォルトの名無しさん
07/05/10 19:38:09
だーから相手すんなってば。
相手するなら誘導してやれ。

521:デフォルトの名無しさん
07/05/10 22:03:02
>>515
ですけどもういいです。もっとできる人探しておしえてもらいます。
ここにいる人達はどうせこのプログラムがかけないんでしょ?
こんなしたてに聞いているのにひどい人達ですね。みなさんわからない
時期はなかったんですか?

522:デフォルトの名無しさん
07/05/10 22:07:50
君は自分の要求を受け入れる人の言うことにだけ耳を傾けるのかね。

523:デフォルトの名無しさん
07/05/10 22:24:34
>ここにいる人達はどうせこのプログラムがかけないんでしょ?
こういうこと言うやつに何も教える気は無い、消えろ。
その聞き方じゃどこ行っても同じだぞ、初心者にしか相手してもらえない

524:デフォルトの名無しさん
07/05/10 22:26:54
少なからず相手しちゃってる件

525:デフォルトの名無しさん
07/05/10 22:26:59
ネタにマジレスカコイイ

526:デフォルトの名無しさん
07/05/10 22:30:26
でしょでしょエヘヘ

527:デフォルトの名無しさん
07/05/11 01:53:21
でも実際こういう新入社員は居る事実。

528:デフォルトの名無しさん
07/05/11 16:58:23
>>521を本人が書いているという保証はどこにもないなあ・・・。


529:デフォルトの名無しさん
07/05/11 17:41:56
だから?

530:デフォルトの名無しさん
07/05/11 21:21:44
疑問文に感嘆符つけて質問する奴は俺の中ではスルー対象だわ。
非常に高い確率でDQNだからな。相手してられん。

531:デフォルトの名無しさん
07/05/11 21:23:12
疑問文に感嘆符とはどういうことだね!

532:デフォルトの名無しさん
07/05/11 21:35:48
?!

533:デフォルトの名無しさん
07/05/11 21:37:02
>>530
感嘆符つけて質問する奴なんてお前のレス以前に見たこと無い。

534:デフォルトの名無しさん
07/05/11 21:39:36
勘違いしつつぼやく奴は俺の中ではスルー対象だわ。
非常に高い確率でDQNだからな。相手してられん。

535:デフォルトの名無しさん
07/05/11 21:43:23
インテロバーング

536:デフォルトの名無しさん
07/05/11 21:46:44
疑問符と感嘆符を間違える奴は俺の中ではスルー対象だわ。
非常に高い確率でDQNだからな。相手してられん。

って、スルーできてねーっつーの。

537:デフォルトの名無しさん
07/05/14 13:03:18
今こそスルー力が試されるとき!

538:デフォルトの名無しさん
07/05/14 13:34:27
throw new NullPointerException("ぬるぽ");

539:デフォルトの名無しさん
07/05/14 15:05:17
try {
 >>538
} catch(Exception e) {
 System.out.println("ガッ");
}

540:デフォルトの名無しさん
07/05/14 15:06:41
Javaはスレ違い。
C言語で書け!!

541:デフォルトの名無しさん
07/05/14 15:06:53
>>483
あんまり暴れるな

「IDが一致してたら表示」でいいんだよね

FDからIDを1つ取ってくる
それをPCのファイルのIDを照らし合わせて一致したら表示
次のIDをFDから持ってきて上を繰り返す

という手順でいいんじゃない?
いまケータイだからソースは載せられんけど

542:デフォルトの名無しさん
07/05/14 16:43:12
>>541
>あんまり暴れるな
君みたいに、いちいち反応する連中がいなくなってくれれば
もっと早く収束してたんだろうけどね。

543:デフォルトの名無しさん
07/05/14 16:47:37
あまりにくだらない

544:デフォルトの名無しさん
07/05/14 17:24:35
>>542
いちおう>>541はやり方書いてるけど?

545:デフォルトの名無しさん
07/05/14 18:18:25
>>544
は?関係ねえよ。
>>486

546:デフォルトの名無しさん
07/05/14 18:36:30
てst

547:デフォルトの名無しさん
07/05/14 21:56:34
>>545
とりあえずおまいが氏ね

548:デフォルトの名無しさん
07/05/15 23:15:56
どなたか
URLリンク(www.cns.ci.ritsumei.ac.jp)
の08、09の解析をしていただけないでしょうか?

549:デフォルトの名無しさん
07/05/15 23:22:45
>>548
スレ違い

550:デフォルトの名無しさん
07/05/20 06:03:52
整数12ビットの列を扱うには、構造体のビットフィールドを使うしかないのでしょうか?

551:デフォルトの名無しさん
07/05/20 06:33:12
16bitなり32bitなりで読み込んで
必要な部分だけマスクして取りだしゃいい。

それでも外部に記録されているものを読み書きする場合には
エンディアン依存は避けられないが
ビットフィールドよりはまし。

552:デフォルトの名無しさん
07/05/20 13:14:54
charを介して変換すればマシンのエンディアンには依存しない
どう変換するかは元データのエンディアンによる(6ビット1バイトだとすれば)

553:デフォルトの名無しさん
07/05/20 17:36:09
どうせ外部とのI/Fなら、コンパイラもセットで依存し捲くってもいいというコンセンサスを得た上で
ビットフィールドを使うのが一番楽だと思うが。
#後は野とn(ry

554:デフォルトの名無しさん
07/05/20 22:00:06
そしてBeOSの悲劇

555:デフォルトの名無しさん
07/05/21 16:02:25
1000までの素数を求めて出力するプログラムの作成を教えてください。
mod使う方法で。


556:デフォルトの名無しさん
07/05/21 16:14:04
mod 素数 C言語あたりでググったほうがはやい

557:デフォルトの名無しさん
07/05/21 16:15:12
つか、Cでmod使えとは。
>>555
宿題スレへ行け。そしてもう来るな。

558:デフォルトの名無しさん
07/05/21 16:18:27
#define mod(a, b) ((a) % (b))

559:デフォルトの名無しさん
07/05/21 17:27:29
inline int mod(int a, int b) { return (a % b); }

560:デフォルトの名無しさん
07/06/04 00:15:06
ファイルの行数を数えてその分配列を確保したいのですが、
このような配列の使い方(foo関数の部分)をしていいのでしょうか?
malloc()した方がいいんでしょうか。

よろしくお願いします。

int main()
{
  int line_count;

file_line_count(&line_count); //ファイルの行数を数える関数
foo(line_count);
}

void foo(int line_count) //foo関数
{
  int array[line_count]:
       ^^^^^^^^^^^^^^
  :
  :
}

561:デフォルトの名無しさん
07/06/04 00:33:19
>>560
対象とする規格による。いわゆる C99 なら標準で認められている。
C99 より前の C の規格や現行の C++ では認められていない。

562:デフォルトの名無しさん
07/06/04 00:34:16
>>560
そのような可変長の配列はC99で採用された仕様だから、
一部のC89信者に蛇蠍の如く忌み嫌われる。

まぁ、C99限定でいいのなら使っていいと思うよ。
但し、スタックサイズに注意すること。

563:デフォルトの名無しさん
07/06/04 02:47:44
関係ないけどファイルの行数を数える関数で戻り値使わないでポインタ渡しなのが気持ち悪い・・・

564:デフォルトの名無しさん
07/06/04 02:51:17
昔あった、関数は全部voidで宣言しろっていうとんでもないコーディングルールを思い出した

565:デフォルトの名無しさん
07/06/04 04:45:24
>>564
戻り値を表示できるデバッガが無かったとか?

566:デフォルトの名無しさん
07/06/04 08:22:36
でも結構しっかりしたC用のAPIだと戻り値はエラー状態を表すのに使われていて、
本来戻り値になるであろうものもポインタの引数になるというのはよく見かける。

567:デフォルトの名無しさん
07/06/04 08:33:37
MPI とかそんな感じだったような。

568:デフォルトの名無しさん
07/06/04 09:41:44
余計 void はありえないなw

569:デフォルトの名無しさん
07/06/04 11:30:55
戻り値のチェックを忘れる馬鹿がいるから、とかじゃね?

570:デフォルトの名無しさん
07/06/04 11:36:05
is〜な問い合わせ関数でも、戻り void でステートをポインタ引数に取るのか…
たまんねーコーディング規約だな

571:デフォルトの名無しさん
07/06/04 23:25:39
>>570
うんにゃ
ポインタは渡さない
後はわかるな?

572:デフォルトの名無しさん
07/06/04 23:33:04
よりよってグローバル変数かよ。

573:572
07/06/04 23:33:55
"に"が抜けた。

×よりよってグローバル変数かよ。
○よりによってグローバル変数かよ。

574:デフォルトの名無しさん
07/06/04 23:52:32
>>572-573が妙にイラッと来る

575:デフォルトの名無しさん
07/06/05 00:02:58
×>>572-573が妙にイラッと来る
>>572-573が妙にムラッと来る

576:560
07/06/05 00:03:24
>>561
>>562
有難うございます。

色々つっこまれてる。(;゚□゚)

577:デフォルトの名無しさん
07/06/05 05:00:17
>>571
まあ、N88-BASIC のコードを移植するプロジェクトならアリかもしれんが・・・。

578:デフォルトの名無しさん
07/06/05 13:40:27
>>572
eax だってグローバル変数だー (i86系)

579:デフォルトの名無しさん
07/06/05 13:42:30
スマン環境依存スレじゃなかった

580:デフォルトの名無しさん
07/06/05 13:42:38
>>578
いくらなんでもスレ違い。どっか他所でやってくれ。

581:デフォルトの名無しさん
07/06/05 13:53:48
レジスタはスレッド切り替わる時に退避されるからスレッドセーフで、
グローバル変数なんかとは格が違う。

582:デフォルトの名無しさん
07/06/05 14:01:55
>>581
>580

583:デフォルトの名無しさん
07/06/13 23:07:43
スレリンク(prog板:758番)

char *data = 30000;
↑これに対して↓を行うと
gcc -fsyntax-only -x c -std=c99 -pedantic -Wall -Wextra

:1: warning: initialization makes pointer from integer without a cast

と警告は出るけどエラーにはならない。あれ?と思って規格を見た。

6.7.8 Initialization p11 に
"the same type constraints and conversions as for simple assignment apply"
とあったので 6.5.16.1 Simple assignment の Constraints を見たけど、
左辺ポインタで右辺が整数というのは認められないように見える。

規格ではエラーになるべきなんじゃないの?
ちなみに C++ では思ったとおりエラーになった。

584:デフォルトの名無しさん
07/06/13 23:09:15
暗黙の・・・

585:デフォルトの名無しさん
07/06/22 04:01:03
ファイルサイズの取得方法って、「ftell」を使用するのが常道なんでしょうか。

Cでファイルサイズを取得する場合、自分は「fgetpos」を使用すのかなーと漠然と考えていて【B】のようなソースを考えていたんですが、
>>402がファイルサイズの取得方法として「ftell」を利用してるとのことだったので、【A】のようなソースも考えてみました。
やはりAのほうがよいのでしょうか。。。

========================
【A】
========================
long size = 0L;
FILE *fp = NULL;
fp = fopen( "hogehoge.jpeg", "rb" );
if ( fp == NULL ) {
 /* エラー処理 */
} else {
 if ( fseek( fp, 0L, SEEK_END ) != 0 ) {
  /* エラー処理 */
 } else {
  size = ftell( fp );
  if (size == -1L ) {
   /* エラー処理 */
  }
  if ( fclose( fp ) != 0 ) {
   /* エラー処理 */
  }
 }
}
/* sizeの値がhogehoge.jpegのファイルサイズ */

586:585
07/06/22 04:01:52
で、Bです。
========================
【B】
========================
fpos_t *pos;
FILE *fp = NULL;
fp = fopen( "hogehoge.jpeg", "rb" );
if ( fp == NULL ) {
 /* エラー処理 */
} else {
 if ( fseek( fp, 0L, SEEK_END ) != 0 ) {
  /* エラー処理 */
 } else {
  if ( fgetpos( fp, &pos ) != 0 ) {
   /* エラー処理 */
  }
  if ( fclose( fp ) != 0 ) {
   /* エラー処理 */
  }
 }
}
/* posの値がhogehoge.jpegのファイルサイズ */
/* fpos_tってキャストできそうだからサイズの値が取れると思ったのですが。。。 */
========================


587:デフォルトの名無しさん
07/06/22 04:02:02
環境依存の方法を使うのが普通じゃないかな。

588:デフォルトの名無しさん
07/06/22 04:04:05
>>586
全然本質じゃない細かいところで
> fpos_t *pos;
これは
fpos_t pos;
だよね。多分わかってはいるとは思うんだけど。

589:デフォルトの名無しさん
07/06/22 04:14:58
fpos_tって別の変数にキャストしたりするとき困らない?

fpos_tって環境依存だからlong long型とは限らないと聞いたことがある。


590:デフォルトの名無しさん
07/06/22 04:19:29
横からすみません。

この>>585って、もしhogehoge.jpegのファイルサイズが巨大だった場合、
どうなっちゃんですか?

591:デフォルトの名無しさん
07/06/22 05:16:26
標準Cでは2GBを超えるファイルのサイズを知る手段はないって結論になる。
fpos_tがキャスト可能であることは保障されていないことだし。

ファイル関連は標準Cだけで書くのを諦めて、64ビット系のstat()相当の関数を使うのが無難じゃない?

592:デフォルトの名無しさん
07/06/22 06:19:36
>>587〜のみなさん、ありがとうございました(588さんご指摘ありがとうございます)。
ファイルのサイズが大きい場合のことまで頭が回っていませんでした。
標準Cでは難しそうですね。
stat等の機能を持つ関数使用が無難といったところでしょうか。
一応stat使用時のソースも考えてみましたが…

struct stat fInfo;
if ( stat( "hogehoge.jpeg", fInfo ) != 0 ) {
 /* エラー処理 */
} else {
 /* fInfo.st_sizeにファイルサイズが入る */
}

あるいは・・・非 POSIX 標準 API インタフェースで(UX上で動作)

struct stat64 fInfo;
if ( stat64( "hogehoge.jpeg", fInfo ) != 0 ) {
 /* エラー処理 */
} else {
 /* fInfo.st_sizeにファイルサイズが入る */
}









593:デフォルトの名無しさん
07/06/22 07:49:47
相乗り質問ですいませんが
ファイルサイズ自体を知りたいのではなくて
ファイルサイズがある一定値を超えているか否かを判定したい場合も、
やはりstatなりftellなりでバイトサイズを一度取得してから
if文で判定するしかないですよね。

2GBだろうが3GBだろうが、とにかくある値を
超えてるか超えてないかだけわかればいいのですが。。。

594:デフォルトの名無しさん
07/06/22 08:16:12
ファイル開いたらある値まで無理矢理ファイルポインタ動かしてみて
エラーが出るかを拾うってのはどうだろう
やっぱ2GB超えちゃうとダメなのかな

595:デフォルトの名無しさん
07/06/22 08:36:48
そもそもファイルが開けないとサイズが調べられないプログラムはどうかと思うんで、
stat64 なりで調べた方がいいと思うよ。

596:デフォルトの名無しさん
07/06/22 08:45:05
ていうかPOSIX環境だと_FILE_OFFSET_BITS=64が無ければ
2G以上のサイズはのopen/fopen自体が失敗する。
Windows環境だとopenは出来るけど、seekが出来ない(シーケンシャルには読める)。
それぞれ、open64や_lseek64(bccには無い)を使う。
もちろん、_FILE_OFFSET_BITS=64なら、openだけでよい。

また、statも同様に、_FILE_OFFSET_BITS=64ならstatだけで良いが
それ以外はstat64等を使う。

597:デフォルトの名無しさん
07/06/22 09:31:14
そもそもfseek()はエラーを返せない。

598:デフォルトの名無しさん
07/06/22 09:54:27
stat構造体のst_sizeはoff_t型だから、……
long int型になるのかな、
そうするとlong int型に格納しきれないバイト数のファイルは
桁あふれするのかな? 0? 再現させてテストしたいが
環境が手元にないのだが。。。。。。

599:デフォルトの名無しさん
07/06/22 10:00:42
だからoff_t型の大きさは_FILE_OFFSET_BITSや_LARGEFILE64_SOURCEによって変わる。
off_tに格納できないようなサイズのファイルは、そもそもstat自体が失敗する。

600:デフォルトの名無しさん
07/06/22 10:07:58
あ、Windowsだとstatは失敗しないな。たぶん。
で、結果がどうなるかは処理系(ライブラリ)依存。
何故ならstatはエミュレーションしているので、
stat("c:/*", &st)が成功してしまったりする処理系があるから。

601:デフォルトの名無しさん
07/06/22 11:44:19
ファイルサイズというのが何を意味するかによる。
OS上でのサイズのことなら、
そもそも環境依存なので環境に用意されたAPIを好きなように使えばいい。
Cの入出力関数で読んだときのバイト数のことなら、
読めないようなものは無視してしまえばいい。

まあ、なんでファイルサイズを知りたいのかってとこまで
一回さかのぼって考えてみるのも一計。

602:デフォルトの名無しさん
07/06/22 22:25:44
サイズは「サイズ」以外ないだろ。
「文字数」とは違う。

603:デフォルトの名無しさん
07/06/23 08:17:34
昔のCP/Mはセクタ数でしか管理してなかったなぁ

604:デフォルトの名無しさん
07/06/23 08:53:01
>>603
今のCP/Mとやらはどう管理しているの?

605:デフォルトの名無しさん
07/06/23 09:23:37
>>603
最終セクタの0x1Aまでがファイルの「サイズ」だろ?

606:デフォルトの名無しさん
07/06/23 09:45:36
でもそれは管理されてない。

607:デフォルトの名無しさん
07/06/23 09:54:38
ん、「管理されているかどうか」という話なの?
「ファイルのサイズとは何か」という話の揚げ足を取ろうとして墓穴を掘っただけじゃなかったの?

だったらそれでいいけど。

608:デフォルトの名無しさん
07/06/23 09:57:38
あっと、
「ファイルのサイズとはOSに管理されていなければならない」という
話の流れとは関係ないことを言いたかっただけで
「ファイルのサイズとは一意に決まるものである」ということに対する反論じゃなかったって事ね。

609:デフォルトの名無しさん
07/06/23 10:25:40
バイナリファイルは「0x1aまで」というルールを採用できないからセクタ単位でしかサイズを得られない。

610:デフォルトの名無しさん
07/06/24 03:19:11
ファイルシステムがファイルのサイズをセクタ単位でしか管理してない上に、
テキストとバイナリで終端の扱いが違うようなシステムだって存在してたんだ。
統一した「ファイルサイズを得る方法」なんてあるわけがない。

あー、それから人の書き込みが何でも揚げ足取りに見えるとしたら重症だぞ。


611:デフォルトの名無しさん
07/06/24 03:23:51
ファイルサイズを取得する関数が標準で用意されなかったのは、
そのあたりが理由なのかな?

612:デフォルトの名無しさん
07/06/24 04:03:56
>>611
そそ、ファイルシステムという概念も統一できないからディレクトリ操作関係も入れられていないし
ファイル操作もストリーム処理系を除くとremove()位しかない。

613:デフォルトの名無しさん
07/06/24 04:31:09
MS-DOS 1.0 もディレクトリないんだっけ?

614:デフォルトの名無しさん
07/06/24 04:43:31
汎用機もねーよ

615:デフォルトの名無しさん
07/06/24 22:22:42
C言語をはじめたばかりであまりわからないのですが、
ビットシフトはなんの役に立つのでしょうか?

616:デフォルトの名無しさん
07/06/24 22:24:17
そのネタ飽きた

617:デフォルトの名無しさん
07/06/25 10:05:04
そういや、xmodemプロトコル(無印)もファイルサイズの概念無かったな
128バイトのブロック単位だったからファイルの後ろにはゴミがついていた
Mac専用にファイル名やサイズをヘッダにつけるマックバイナリができたっけ・・

618:デフォルトの名無しさん
07/06/25 10:55:57
マックバイナリができた事情はリソースフォークの管理のためだが詳細はスレ違いにつき割愛。

619:デフォルトの名無しさん
07/06/25 11:58:13
リソースフォークの話は出してくるやつが出ると思った
リソース/データフォークのサイズもファイルサイズの指定の意味で
書いたんだがわからなかったんだろう


620:デフォルトの名無しさん
07/06/25 15:09:30
>リソース/データフォークのサイズもファイルサイズの指定の意味で
>書いたんだがわからなかったんだろう
これ日本語なの?

621:デフォルトの名無しさん
07/06/25 19:06:14
まるでXMODEM対応のためにマックバイナリが作られた様な表現はどうと思う。

622:デフォルトの名無しさん
07/06/25 19:07:17
どうと思う!
いや、どうかと思う、だorz

623:デフォルトの名無しさん
07/07/01 14:39:59
MFCでCString型の変数strにメタ文字の.が入っている場合\記号と連結するのに
str = "\\" + str;
これで全然問題ないのですが、標準のCで
char str[MAX_PATH];
strcpy(str, ".");
starcat("\\", str);
こうするとアクセスバイオレーションが発生します
どうしたらええの?
strcpy(str, "\.");これでも駄目だった
そうそう環境はWinXPSP-2、VC6です


624:デフォルトの名無しさん
07/07/01 14:41:45
>>623
starcat なる謎の関数の仕様をよーく確認しろ。

625:デフォルトの名無しさん
07/07/01 14:42:52
星猫

626:デフォルトの名無しさん
07/07/01 14:46:52
スマンstrcatだったMSDN見ても問題ないと思うのだが?
文字列の連結するんだよねstrcatって、まぁ今回は連結する方もされる方も一文字だったが

627:デフォルトの名無しさん
07/07/01 14:48:00
>>626
じゃぁ strcat の仕様をよーく確認しやがれこのバ

628:デフォルトの名無しさん
07/07/01 14:48:55
そりゃ文字列リテラルに文字列を追加しようとしたら落ちるわな。

629:デフォルトの名無しさん
07/07/01 14:50:02
それでもstarcatならきっとやってくれるさ

630:デフォルトの名無しさん
07/07/01 14:50:05
MFC 使える環境なら CString か std::string 使えば?
そっちの方が幸せになれるよ。セキュリティ的にも。

631:デフォルトの名無しさん
07/07/01 14:56:52
>>628
ところがどっこいリラテルでなくてもアクセスバイオレーションが起こるんだよねこれがまたww
>>630
だからMFCなら全然無問題なのだが、Cの事も知りたいからよ

632:デフォルトの名無しさん
07/07/01 14:56:54
>>626
strcatでは、後ろに追加することしか出来ないんだ。
"//"には、後ろにstrを追加する余裕なんて無い。

633:デフォルトの名無しさん
07/07/01 14:59:06
>>631
ならリテラル以外で問題が再現するコードを書いてみやがれ

634:デフォルトの名無しさん
07/07/01 15:00:41
>>631
C は面倒臭いよ。
バッファオーバーフローをいちいち気にしないといけないから。

635:デフォルトの名無しさん
07/07/01 15:04:06
sprintf()一回ですむことをstrcpy(), strcat()を駆使しようとするからそうなる。
しかし、やりたいことがよく判らないからサンプルを書けない。
例えばディレクトリとファイル名を連結したいだけならこうなるのだが。
sprintf(path, "%s\\%s", dir, file)

636:デフォルトの名無しさん
07/07/01 15:08:05
>>631
どうせ初期化してないのに strcat とかしたんじゃないのか?

637:デフォルトの名無しさん
07/07/01 15:12:33
元のCStringを使ったコードはこうなっていると解釈するぞ。
CString str = ".";
str = "\\" + str;

char str[MAX_PATH] = ".";
size_t size = strlen(str) + 1;
if (size >= MAX_PATH)
  abort(); /*好きにしてくれ*/
memmove(str + 1, str, strlen(str) + 1);
str[0] = '\\';
WindowsならTCHAR系使えという気もするが、とりあえずcharにしておいた。


638:デフォルトの名無しさん
07/07/01 15:39:04
BoehmGCのようなライブラリを使えば
char *str = ".", *tmp;
tmp = GC_MALLOC(strlen(str) + strlen("\\") + 1);
sprintf(tmp, "\\%s", str);
str = tmp;
でいいよ

んでも毎回strlen()とかすんのはウザいので、
typedef struct string_t { char *s; size_t len; } string_t;
とかして、string_tに対する操作を関数で一通り作るといいよ

んでもそんなアホくさい作業をするくらいならC++で素直に
std::basic_string<>使ったほうがいいよ

639:デフォルトの名無しさん
07/07/01 15:53:40
MFC使っているならCStringもありさ

640:デフォルトの名無しさん
07/07/01 19:19:12
strcpy -> strncpy
strcat -> strncat
sprintf -> snprintf

641:デフォルトの名無しさん
07/07/01 20:09:50
>>640
残念ながら、前2者は仕様が仕様だから推奨できない。そして最後は未だ標準じゃない。

642:デフォルトの名無しさん
07/07/01 21:07:18
結局C++でstd::basic_string<>なりMFCのCStringなりを使えということになる。
何より楽だし。

643:デフォルトの名無しさん
07/07/01 22:28:15
バッファオーバーフロー脆弱性の話を聞くたびに、
敢えて C を使う以上はエラー処理ちゃんとしろよと思ってしまう。
それができないなら C++ にしる、と。

644:デフォルトの名無しさん
07/07/01 23:19:51
>641
C99は未だ存在しないのか・・・

645:デフォルトの名無しさん
07/07/01 23:22:59
C99 が使える環境では snprintf を使って、
使えない環境なら等価な関数に #define すればいいんじゃない?

646:デフォルトの名無しさん
07/07/01 23:26:40
snprintf()に等価な関数なんてないっしょ。環境によってはあるんだっけ?

647:デフォルトの名無しさん
07/07/01 23:33:00
VC++ には _snprintf がある。

648:デフォルトの名無しさん
07/07/02 00:13:07
char *s;
FILE *fp = fopen("/dev/null", "w");
size_t len = fprintf(fp, ...); /* 長さを数えてもらう */
fclose(fp);
s = malloc(len + 1);
sprintf(s, ...);

勿論こんなコードを使うぐらいならapacheあたりのコードをパクるのが良いが
それぐらいならやっぱりC++を使うべきという結論に

649:デフォルトの名無しさん
07/07/02 00:38:37
>>648
必要なバッファの大きさを求める部分は、関数化して切り出すべきだと思う。
C99ならsnprintf(NULL, でいいし、VCなら_scprintfが使えるし。

650:デフォルトの名無しさん
07/07/02 00:48:37
>>649
そいつらの代替実装の話だろ。

651:デフォルトの名無しさん
07/07/02 00:48:40
問題は移植性の低さだな
標準とはいえC99未対応のCコンパイラは多い

652:デフォルトの名無しさん
07/07/02 01:00:52
snprintf 程度なら、C99 に対応してない処理系でも大抵独自に用意されてるんじゃない?

653:デフォルトの名無しさん
07/07/02 01:09:55
>>652
あってもC99と同じ仕様とは限らん
たとえばSingle Unix Specificationだと、たしか返り血が違うんじゃなかったか

654:デフォルトの名無しさん
07/07/02 03:06:17
その場合は自分でラッパ関数を定義すればいいんじゃないかな?

655:デフォルトの名無しさん
07/07/02 21:29:01
*BSD LIBCあたりから掻っ払って来りゃええやん。

656:デフォルトの名無しさん
07/07/04 22:59:02
ねぇねぇおまえらちょっと教えてくんない
ファイルの行数を取得する標準関数なんてないよね
そんなことがしたい時ってやっぱ一旦ファイルを全部読み込んでそん時に\nの数
数えるとかやってんの?
どうよ


657:デフォルトの名無しさん
07/07/04 23:03:13
そうする

658:デフォルトの名無しさん
07/07/04 23:34:14
それ以外の方法があるなら是非とも教えてもらいたいもんだ

659:デフォルトの名無しさん
07/07/04 23:50:13
fp = fopen(filePath,"r");
while(fgets(szBuff, MAX_PATH, fp) != NULL)
{
  maxLine++;
}
fclose(fp);

char szItem[7][maxLine++];

じゃぁこれはどうよ、二次元配列が作りたくてこうやったら
error C2057: 定数式が必要です、MSDNとか調べてURLリンク(support.microsoft.com)

char szItem[7][((const int)maxLine++];
こうしてもなおんないんだよねぇこれってどうよ

660:デフォルトの名無しさん
07/07/04 23:52:13
スマン訂正
int maxLine;
罰char szItem[7][((const int)maxLine++];
丸char szItem[7][(const int)maxLine++];

661:デフォルトの名無しさん
07/07/04 23:59:58
C99じゃない限り配列の大きさはコンパイル時に固定=定数

662:デフォルトの名無しさん
07/07/05 00:07:53
あきらめきれなくて
回避策はないのかと聞いてみる

663:デフォルトの名無しさん
07/07/05 00:09:15
URLリンク(www23.atwiki.jp)
のwikiに載っていたリサージュのプログラムで
x = cos(2 * PI * a * t);
y = sin(2 * PI * b * t);
の2の値を自由に変えられる(自分で入力できる)ように
したいんですけど、どうやったらいいですか?


664:デフォルトの名無しさん
07/07/05 00:10:28
>>662
malloc使えばいいんじゃない

665:デフォルトの名無しさん
07/07/05 00:12:44
>>664
クワシク

666:デフォルトの名無しさん
07/07/05 00:17:10
そこらへんの入門書に書いてある。
残念ながらここで1から説明していられるほど簡単に説明できる機能ではない。

667:デフォルトの名無しさん
07/07/05 00:53:10
>>662
寧ろ、C++でstd::vector使えばいいんじゃない?

668:デフォルトの名無しさん
07/07/05 01:32:50
ドウシテC99ヲツカワナイノデスカ

669:デフォルトの名無しさん
07/07/05 16:48:51
ドウシテC99ガフキュウシテルトオモウノデスカ

670:デフォルトの名無しさん
07/07/05 16:50:55
C99 使うくらいなら C++ 使う

671:デフォルトの名無しさん
07/07/05 16:52:17
んだな

672:デフォルトの名無しさん
07/07/05 23:13:16
単項演算子の+って、どう言ったときに役に立つのでしょうか?
Cだけの話ではないかもしれませんが。

673:デフォルトの名無しさん
07/07/05 23:13:35
メジャーなコンパイラでC99に対応してないのってあるの?
俺趣味グラマでgccしか使わんからわからん。

674:デフォルトの名無しさん
07/07/05 23:16:17
>>673
VC++

675:デフォルトの名無しさん
07/07/05 23:20:05
>>672
桁合わせくらいには役に立つことはあるかも。

676:デフォルトの名無しさん
07/07/05 23:47:34
>>672
-があるから+も装備したらしい

677:デフォルトの名無しさん
07/07/06 00:45:33
昔、
#ifdef xx
# define SYM 10
#else
# define SYM
#endif
のような時に

int num = SYM +0;
というような使い方をした覚えがあるような無いような。

678:デフォルトの名無しさん
07/07/06 01:20:07
マクロ関連で役に立つことがたまにありそうではあるな。

679:デフォルトの名無しさん
07/07/06 01:35:03
正確には、式に単項演算子をつけない場合は+を省略したものとみなされる・・・じゃなかったっけ?

680:デフォルトの名無しさん
07/07/06 01:36:20
単項+のオペランドも式だし、
単項+のオペランドになれない式もあるだろ。

681:デフォルトの名無しさん
07/07/07 03:44:31
#ifdef xx
# define SYM 10
#else
# define SYM 0
#endif
では、何故ダメだったのか教えてほしい。

682:デフォルトの名無しさん
07/07/09 22:11:51
学校でC言語実習やったんだがどうしてもわからないことがあったんで聞いてみる。
○×ゲームを作るプログラムを作っていたんですが。
1〜9の数字キーでどこのマスを使うか決めるプログラムなんです。
line1[10]=" 789\n",
line2[10]=" 456\n",
line3[10]=" 123\n",
という行があるんだが↑このスペース間をTabキー使って開けたらエラーが出たんですが
何故Tabキー使っては駄目なのか教えていただけませんか?

683:デフォルトの名無しさん
07/07/09 22:17:17
>>682
書き換える前後で strlen(line1) の数値を比べてみれば分かるんじゃないかな

684:デフォルトの名無しさん
07/07/09 22:37:32
いやコンパイルエラーになるんだろ。
たぶん、構文的に駄目になっているのだろうとしか言えない。
後できちんと規格書に当たってみる。

とりあえず、文字列リテラルの中でタブ文字を表現したければ、
タブを直接入力する代わりに\tを使えばいいと言っておく。

685:デフォルトの名無しさん
07/07/09 22:44:18
>>683
ほんとにCはかじったばっかりなんでよく分からない上に
今気づいたんだけどスペースに半角使用してしまったため↑の位置が変すぎる('A`)
"と7のスペースね。

strlenって言ったら文字列の長さだよね?
Tabキーのスペースは普通のスペースの何個分もあるけど1カウント?しかしないという解釈でいいのだろうか?

686:デフォルトの名無しさん
07/07/09 22:48:07
>>685
やってみたほうがよく分かる

687:デフォルトの名無しさん
07/07/09 23:05:02
>>684
指導書に基づいてプログラム作ってるんだ。
基本的に書き換え不可だからそういうことはできないんだ
>>686
ほんとに実習でやってるだけだしそんな環境ないんだけど('A`)

688:デフォルトの名無しさん
07/07/09 23:12:54
環境もないのに実習なんて言うのか?

689:デフォルトの名無しさん
07/07/09 23:28:53
>>688
ヒント:やるのは学校今は家にいる
学校のPCは勝手に使っちゃいけないんだ。

690:デフォルトの名無しさん
07/07/09 23:30:22
じゃぁ学校でやれよ。ここで文句言われてもどうしようもない。

691:デフォルトの名無しさん
07/07/09 23:32:15
>>689
今書き込みをしているのが自分の自由に使えるPCからなら、
開発環境をインストールすることを勧める

692:デフォルトの名無しさん
07/07/09 23:36:48
>>691
今やってみたがページが真っ白のまま止まってしまう。
ダメみたいだ/(^o^)\

693:デフォルトの名無しさん
07/07/09 23:38:11
とりあえずお前はCの勉強する前にPCの勉強をしろ。

694:デフォルトの名無しさん
07/07/09 23:40:29
>>692
Windows Vista と予想

695:デフォルトの名無しさん
07/07/09 23:49:11
やっぱり聞くんじゃなかったかな。
もう書かないよ。僕のせいで13レスも進んでしまって申し訳ない。

696:デフォルトの名無しさん
07/07/09 23:54:59
そりゃあんた、初心者スレなりに行けばいいものをこんなスレに書くからだ。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5330日前に更新/213 KB
担当:undef