fgetsと次のように宣言されたバッファを使用して.txtファイルから学生の名前と成績を1行ずつ読み取るプログラムがあります。
char buffer[1024];
これで、ファイルは1行の文字列「end」で終了するはずです。
whileループにいつ終了するように指示するにはどうすればよいbuffer == "end"
ですか?
使っstrcmp
てみましたが、なんらかの理由でセグフォールトします。
あなたの質問に簡単に答えるために、 strcmp は実際にあなたが探している関数です:
#include <string.h>
if(!strcmp(line, "end\n") || !strcmp(line, "end\r\n"))
break;
または同様の方法でうまくいくはずです。!
文字列が一致する場合、strcmp は 0 (つまり false) を返すため、strcmp の前にあることに注意してください。しかし、質問ですでに strcmp について言及しているので、あなたはすでにそれを知っていると思います。
segfault の問題について: strcmp に渡すポインタが NULL でないことを確認しますか? ほとんどの C 標準ライブラリはここでエラー チェックを行わず、でメモリを読み込もうとすると segfault が発生します*(0)
。
私の頭に浮かぶ可能性のある別の問題は、 strcmp の使用はもちろん、バッファーを単一の文字列の配列に既に分割している場合にのみ機能することです。strtok_r
はおそらくこのタスクに最も適しています (ただし、使用するのはかなりトリッキーです)。
char *fgets(char *restrict s, int n, FILE *restrict stream);
fgets() 関数は、n-1 バイトが読み取られるか、a が読み取られて s に転送されるか、ファイル終了条件が検出されるまで、ストリームから s が指す配列にバイトを読み取ります。その後、文字列は null バイトで終了します。
したがって、文字列「end」を読み取るとき、バッファ内の要素は {'e', 'n', 'd', '\n', '\0'} である必要があります。次のように strcmp を使用できます。
size_t len = strlen(buffer);
if (buffer[len - 1] == '\n')
{
buffer[len - 1] == '\0';
}
if (strcmp(buffer, "end") == 0)
{
//end
}
また
if (strncmp(buffer, "end", 3) == 0)
{
//end
}
を使用strncmp(buffer, "end", 3)
して最初の 3 文字を比較し、if(3 == strlen(buffer)
end が行を開始していないことを確認すると、問題が解決するはずです。
ファイル内のテキストのフォーマットが固定されている場合はフォーマットされた IO を使用し、ループには !EOF を使用しないのはなぜですか?
例えば:
while(fp!=EOF)
{ fscanf(fp,"%s %s %d",name,grades, &marks);
printf("Name: %s\tGrade: %s\t Marks: %d\n",name,grade,marks);
}
これにより、ファイルの終わりが自動的に検出され、テキスト ファイルに文字列 'end' があるという条件も削除されます。