0

ファイルを読み込もうとしていて、新しい行に到達するまで各文字を読み込んで、その行で何らかの作業を行います。これが私がこれまでに行ったことです:

  char line[] = "";
  char *charcter = "";

  //If i do this here it works fine, but below it's not working at all
  charcter = "asssss";
  strcat(line,charcter);

  //Read file
  inputFile = fopen(fileName,"r");
  if (inputFile) 
  {
    while ((charcter = (char)getc(inputFile)) != EOF)
           strcat(line,charcter); //This piece code keeps crashing my program on run

    fclose(inputFile);
  }

私は C# 開発者ですが、このことを理解できないことに本当に不満を感じています。助けてください。

編集:

ピースラインを変更し、次のようにメモリを割り当てました。

char *line = (char*)malloc( 400 *sizeof(char));

これで、while ループの strcat が機能しますが、すべての値を取得した後にクラッシュします (入力は割り当てられたメモリよりもはるかに小さい)。同じ strcat ステートメントを if ステートメント内に配置すると、最初の文字が取得されてからクラッシュします。

ここで何が問題なのですか?

4

2 に答える 2

2

スタック上の配列内の文字列を変更しようとしています。line[]as ""(つまり、1 バイト、文字) を割り当ててから、 (最初の引数が指すメモリを変更する) でnullメモリを走り書きしようとします。strcat

ソースのテキストに文字列を入れて、それを関数の配列変数に割り当てると、関数の呼び出しフレームのスタックにその量のメモリが割り当てられます。その後にメモリにアクセスすると、スタックの他のビットに走り書きが発生し、データだけでなくプログラムの動作も変更される可能性があります。

これは、C# で固定配列を作成し、それに追加しようとするようなものです。配列の末尾の後に発生する他のメモリに上書きする必要があるため、言語ではそれができません。C では試してみることができますが、所有していないメモリを走り書きしているためにクラッシュするか、さらに悪いことに、それを実行してから不明な状態で実行を続けることができます。のアドレスから数バイト離れた場所に他に何があるかは誰にもわかりませlineん。あなたはそうしない。

詳細については、この質問を参照してください:文字列リテラル: どこに行くの?

メモリアドレスへのポインターを取得すると、C はそれがポインターであることのみを認識します。指しているメモリの種類 (静的定数、スタック、ヒープ) がわからないため、この間違いを犯す可能性があります。間違いを犯した場合、オペレーティング システムはセグメンテーション フォールトを発生させて「実際にはノー、それは許可されていません」と言うかもしれませんし、より微妙なバグの場合はそうではないかもしれません。

ファイルに適合するのに十分な (危険)で大きなバッファーをmalloc割り当てるか、バッファーを再割り当てして毎回拡張する必要があります。

編集lineではchar[]ないことに気付いたchar*ので、回答を編集しました。

于 2013-09-26T13:38:12.233 に答える
2
  • 文字は使用できませんstrcat()- 文字列が必要です
  • 文字変数の型はint( のプロトタイプを確認してくださいgetc())
  • それでも文字ごとに実行したい場合は、インデックスで文字列に追加することを検討してください(そして最後にNUL終了します)
于 2013-09-26T13:38:25.020 に答える