C言語なら、俺に聞け! <8>

このエントリーをはてなブックマークに追加
サイトが広いから探せない。
すいません、初心者です。 下の方法はおかしいでしょうか
どうしても返ってきた時distの値が切れてしまうんです(実際は構造体のメンバからのコピー)
strcpyの後でprintしても切れてしまいます 鬱
main()
{
  char *dist = NULL;

  func(&dist);
  printf("%s \n",dist);
  exit(0);
}
func(char **dist)
{
  char src[] = "TEST STRINGS";
  *dist = (char *)realloc(*dist,strlen(src)+1);
  strcpy(*dist,src);
}
938937 :01/12/02 08:12
あわわ、やっぱりしょうもない間違いでした −_−;
コピーの手前でlength=strlen(structsrc->member);メンバの名前を
間違えてました  情けない、、、2時間悩んだよぅ
>>907
Win32 なら構造化例外 (SEH) で捕まえられる。

int isViolated = 0;
__try {
  // やばそうな処理
} __exception (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
{
  isViolated = 1;
}

UNIX だと SIGSEGV に対応するシグナルハンドラを登録すれば、アクセス保護違反が
発生した瞬間にシグナルハンドラが呼ばれる。ただし、そのときに適切な処理を行うた
めには、設計段階でアクセス保護違反が発生しうることを想定しておく必要がある。後
づけてコードを追加するのは、けっこう難しい。
940デフォルトの名無しさん:01/12/02 09:28
ロギングについてご助言下さい。
複数のプロセスから fprintf() で
一つのログファイルに書き出す場合の排他処理の定石は?
特別なこと(排他処理)をしなくてもうまく書き込めている
気がするのですが木の精ですか?
同じようなことをバッファリングなしで putc() で行うと
ログファイルがぐちゃぐちゃになります。
バッファリングとか fprintf() の実装とか関係ありますか?
あとログファイルのローテーションはどう実装したらよいですか?
>>940
ログ専用プロセスを用意してそいつとプロセス間通信。
ローテーションもそのプロセスがやればよい。
942デフォルトの名無しさん:01/12/02 10:29
>>940
write()で一つのブロックを一回で追加書きこみが定石。
ファイルアクセスはそれ自体が排他的なんで、追加書きこみなら
何も気にしなくて良い。
943デフォルトの名無しさん:01/12/02 10:30
>>902 それなら、納得です。
いや、本みたら、ポインタ変数に直接、入力した値が書き込まれるみたい
に書いてあったので、へっ?って思ったけど、そのアドレス先の実体だけに
書き込んでいるのですね。 だからscanf( "%d" , &a)で入力した値は
aに書き込まれて,&aの値(番地)は入力前も入力後も同じですよね。
質問なんですが(厨な質問でしたらゴメンナサイ)、なぜ
scanf()を使うのがよくないんですか?
誰か説明してくれませんか?初めて知りました・・・
scanf()を使うのがよくないって誰か書いた?
946デフォルトの名無しさん:01/12/02 12:18
>>945
いや、なんかさっき別の板でも言ってた人いましたし、
ずいぶん前に、知り合いがボソッと言ってました。
何でかって、知り合いに聞いたんですけど難しい言葉を
並べられただけで・・・
自分には理由がわからないんです。だから教えてもらい
たくって・・・
947デフォルトの名無しさん:01/12/02 12:21
>>939
>SIGSEGV に対応するシグナルハンドラ
おっとーそういやそんな仕組みあったな。
つーか、例外が起こったら適当に傷を記録して
そのあと元処理に復帰したいんだけど、なかなかムずいね

Javaってこの辺楽なんだよね。遅くっても許すって感じ
>>946
書式と型や入力数が異なってもエラー検出できないからかな?
CUIやらないんで使った事ないや。
949Kusakabe Youichi:01/12/02 12:33
>>946 デフォルトの名無しさん wrote:
> ずいぶん前に、知り合いがボソッと言ってました。

その知り合いに聞くってのはだめですか? > scanf()がダメだとかいう人

> 何でかって、知り合いに聞いたんですけど難しい言葉を
> 並べられただけで

なんだ聞いたのですか。
もう少しわかりやすく言ってくれってたのんだらどうですか?
>>949
忘れてました。
でもこの板見つけたから、詳しい人が沢山いるだろうと思って聞いてみました。
>>946
scanf() が使いづらいのは

1. 字句解析
 文字列の並びから、ここまでが数値、ここまでが演算子、といったようにトークンを
 切り出す処理
2. 型変換
 文字列の "1111" を int 型の 1111 に変換するような処理

を一つの関数にまとめてしまっていて、エラー処理などが難しいからでしょう。

実はscanf() の書式指定はかなり強力で(正規表現ほどではないけど、かなりのことが
できる)使いこなすと便利なのですが、それでも

1. 字句解析は getc(), ungetc() で一文字ずつ拾いながら、トークンの切れ目を探す
2. トークンの切れ目が見つかったらところで、トークン種別を確定して itoa, sscanf()
 などで型変換

と 2 段階にした方がつぶしがきくので、よく使われます。
952Kusakabe Youichi:01/12/02 13:23
>>951 デフォルトの名無しさん wrote:
> scanf() が使いづらいのは
>
> 1. 字句解析
>  文字列の並びから、ここまでが数値、ここまでが演算子、といったようにトー
クンを
>  切り出す処理
> 2. 型変換
>  文字列の "1111" を int 型の 1111 に変換するような処理
>
> を一つの関数にまとめてしまっていて、エラー処理などが難しいからでしょう。


あと、ほかのsscanf()などとちがって、改行をまたぐときの問題がありますね。
>>951.952
ありがとうございます。知りたかったことがわかってよかったです。
さて、そろそろ次スレの季節。
他にC言語で、あまりよくないものってあるんでしょうか?

getc,sscanfの他にgetsなんてのはどうなんですか?
>>955
gets() は最悪ですね。バッファオーバーランが防げない。
バッファオーバーランってなんですか?
入力はgetcとsscanfがいいって事ですか?
>>957
とりあえず google 逝け。
>>942
write()では一度に指定したサイズを書ける保障はないので、
ロック -> ファイル末尾へシーク -> 書き込み -> アンロック
の方が確実だと思われ。
960Kusakabe Youichi:01/12/02 14:04
>>955 デフォルトの名無しさん wrote:
> 他にC言語で、あまりよくないものってあるんでしょうか?
>
> getc,sscanfの他にgetsなんてのはどうなんですか?

388ペイジに書いてありますね > gets()
961デフォルトの名無しさん:01/12/02 14:07
gets() では、例えば

 char str[80];  //char 型の str変数を str[0] から str[79] まで 80個確保
 gets(str); //gets でキーボードから文字列を入力

としても、70文字以下の入力だったら問題無いが、80文字以上の入力をされたときになにもできないため、オーバーフローがおきる。
セキュリティーホールになる。

fgets だったら、最大入力可能文字を数字で指定できる。その数字を超えたものは次回の入力にまわせる。
だから、gets は使わず fgets を使うべき。
>>960
すいませんが、特定の本を出されても困っちゃいます。
それに何の本ですか?

>>961
なるほど。そういうことなんですか。ありがとうございます。
>>962
> すいませんが、特定の本を出されても困っちゃいます。
> それに何の本ですか?

Kusakabe 先生のスレ違い/意図不明な書き込みに対する苦情には専門のスレ
が用意されて いるので、ム板では書かないようにお願いします。そのような書き
込みにコメント をつけるのは、彼と一緒に一緒になって荒らし行為をし てるのと
変わりません。

日下部 陽一先生の隔離スレッド void ***
http://pc.2ch.net/test/read.cgi/prog/1006918877/

#同意も反論も不要。なんかあったら↑のスレで言ってくれ。
964Kusakabe Youichi:01/12/02 14:17
>>957 デフォルトの名無しさん wrote:
> バッファオーバーランってなんですか?

たとえば、飛行機が離陸するときに滑走路からはみ出して海に落ちたら痛いですよ
ね。
965デフォルトの名無しさん:01/12/02 14:21
CGIプログラムとして動作させるときは、CONTENT_LENGTHの値から入力されたバイト数が分かる(POSTの場合)ので、gets()でも構いませんよね?
966デフォルトの名無しさん:01/12/02 14:21
> バッファオーバーランってなんですか?

幼女タンのマムコに、大人のチンポを無理やりねじこんだら、子宮破裂するでしょ。
それと同じ。
967デフォルトの名無しさん:01/12/02 14:22
>>965
それを騙す人がいなければ。
というか、ふぇーるせーふ でなるべく使わないに越したことはないかと
968デフォルトの名無しさん:01/12/02 14:23
CONTENT_LENGTHの値ってだませるんですか!?
WWWサーバーソフトが設定するのだとばかり思っていましたが。
969968:01/12/02 14:24
とりあえず、fgetsにします。
>>968
今時 Web サーバにバグがない、なんてことは誰も信じてません(w

まぁ CONTENT_LENGTH が腐ってることはまずないと思いますが、それでも万が一の
ときにバッファオーバーランが発生する(しかも検出できない)のと、エラーをプログラ
ム側で検出してログに残すなり何なりの対処を取るのでは、プログラムの信頼性が
違ってきますし、バグへの対処に要する時間も変わってきます。
赤信号が出てるので新スレ作りました。
速やかに移動してください。
http://pc.2ch.net/test/read.cgi/tech/1007272267/l50
972newbieM:01/12/02 15:12
今ある特定のディレクトリの中のファイル名を比較して
リネームというようなソフトを作ろうと思っているんです。
つまりaっていうフォルダに
abc.txt
efg.txt
・・・・
ってあったとき
abc.txtをエービーシー.txt
efg.txtをイーエフジー.txt
という風に初めからあるリストと比較してリネームしたいんです。
ですが具体的にどのように書いたらいいかがわかりません。
どの命令を組み合わせるかおしえていただけないでしょうか?
>>972
そのプログラムを組むには、いろいろ関数を使います。
もう少し的を絞って質問してください。
それと、新しい、スレに移動もおねがいします。
974Kusakabe Youichi:01/12/02 15:28
>>972 newbieM wrote:
> 今ある特定のディレクトリの中のファイル名を比較して
> リネームというようなソフトを作ろうと思っているんです。

man 5 rename
975newbieM:01/12/02 15:31
了解しました。
早速移動して書き直したいと思います。
が、ほんとにまったくわからないんです。
一つのファイルだけならできるんですが・・・
>>975
プラットフォームは?
977newbieM:01/12/02 15:33
>974さん
意味わからないです(w_−; ウゥ・・
>>977
分からなくていい。>>963 見とけ。
>>977
OSは?
答えはは新スレで
980デフォルトの名無しさん:01/12/02 23:53
>本気で「ひとそれぞれ」だと思っているんだったら、
>「K&Rは難解だとの評価は大多数から既に出ている」とかいう理屈は
>使えないわけですよね:)

「人それぞれ」って「K&Rは簡単ってことになる」と思い込んでいる人もいるようですね:)
っていうか「そういうこと言う人が多いですよ」ということと「理屈は使えない」ってどう繋がるのでしょうね:)
>>980
なに、この人?
名無し登場臭壁チャン
983C初心者:01/12/03 00:05
結城浩せんせのC言語プログラミングレッスンの
EOFまで繰り返せまで進んだんですが僕も話しに加われますか?
>>983
加わってもいいけどもうスレが終わりです。
ちなみに次スレはこれね。

C言語なら、俺に聞け! <9>
http://pc.2ch.net/test/read.cgi/tech/1007272267/