1

カンマで区切られた3つのフィールドを持つテキストファイルがあります。私のテキストファイルの内容の例:12345、真のプログラミング初心者、BS MEファイルをプログラムにロードするために、私は以下のコードを使用しました....私の問題は、コードが機能する場合と機能しない場合があることです(エラーメッセージが表示され、プログラムはそれ自体を閉じて続行しません)。また、テキストファイルが空白(何も書き込まれていない)であることがわかりました。自動的に閉じられ、続行されません。あなたの助けをいただければ幸いです。ありがとう!

int read(){
     FILE *stream = NULL;
     int ctr;
     char linebuffer[45];
     char delims[]=", ";
     char *number[3];
     char *token = NULL;
     stream = fopen("student.txt", "rt");
     if (stream == NULL) stream = fopen("student.txt", "wt");
     else {
          printf("\nReading the student list directory. Wait a moment please...");
          while(!feof(stream)){            
                ctr=0;
                fgets(linebuffer, 46, stream);
                token = strtok(linebuffer, delims);
                while(token != NULL){
                  number[ctr] = linebuffer;
                  token = strtok(NULL, delims); 
                  ctr++;
                }
          recordCtr++;                      
          }                     
     recordCtr--;
     }
     fclose(stream);
}    
4

3 に答える 3

2

token一度見つけたらコピーすることはありません。linebuffer次の行が読み込まれると、そこにあるデータが上書きされるため、コピーすることはできません。

この行:

number[ctr] = linebuffer;

token最近見つかったトークンを保存するために参照する必要がありますが、そうではありません。おそらく1のようなものを読む必要があります:

strcpy(number[ctr], token);

ただし、スペースがあることを確認するために宣言を変更する必要があります。

char number[3][32];

明らかに、これはバッファオーバーランのリスクをもたらします。非常に長いトークンがある場合、それは適合しません。演習として残されたものを最も適切に処理する方法。:)

1 2つの数値を格納するために使用され、1つの文字列(名前)が私を超えているのに、一時ベクトルが「数値」と呼ばれるのはなぜですか。

于 2010-12-02T13:48:37.380 に答える
1

呼び出しfgets()でサイズとして45を指定する必要があります。そうしないと、fgetsがNULLターミネータを書き込むときにバッファをオーバーフローします。これにより、「delims」文字列が空の文字列に設定されます。

また、関数宣言にintが返されると記載されていても、値は返されません。

「structstudent」の定義はわかりませんが、を使用するとバッファがオーバーフローする可能性がありますstrcpy()。また、「recordCtr」をデクリメントします。なんで?書き込み用に開くことができないのに、なぜ書き込み用にファイルを開くのですか?なんで?それも失敗した場合は、NULLポインターでfcloseを呼び出します。それが大いに役立つとは思えません。

「番号」を初期化していないことに気づきました。最初の行に3つの数字が表示されない場合はstrcpy()、初期化されていないポインターから取得します。おそらくNULL値を持っているので、プログラムはセグメンテーション違反になります。

また、サイズ3の配列がありますが、読み取った行に3つを超えるコンマ区切りのフィールドがある場合、配列がオーバーフローします。

おそらく他にも多くのエラーがあります。

多くのプログラマーは、戻り値のチェックや変数の初期化など、すべての優れたコーディング手法をわざわざ行うことはできません。彼らはしばしばこのようなコードで終わります。本当に優れたプログラマーになりたいのであれば、これらすべてのことを行う習慣を身につけるか、少なくとも常に必要かどうかを考えてみてください。

このコードには非常に多くの潜在的なバグがあります。行の長さが45文字を超えるとどうなりますか?改行を削除しません。文字列を数値に変換しないか(number [1]は文字列データのように見えるので、なぜ「numbers」という配列に格納するのですか?)、fgetsが実際にデータを返したことを確認したり、データの数を確認したりしません。得る。

于 2010-12-02T13:55:24.793 に答える
1

買い手に注意させてください。

strtokには、心配すべきいくつかのエッジケースがある場合があります。

「1、2、3」は3つのトークンを生成します。

「1、、3」は2つのトークンを生成します。

于 2010-12-02T14:16:49.767 に答える