0

これは、filmgenieを作成するためのはるかに大きなプログラムの一部であり、何らかの理由で、このwhileループに到達するとプログラムがクラッシュし、私の問題が何であるかがわかりません。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>

FILE *fp, *fopen();
char *arrayoffilms[45];
int main()
{
    char line[100],junk[100];
    fp=fopen("filmtitles.txt","r");
    int i=0;
    while(!feof(fp)) {
        fscanf(fp,"%[^\n]s",line);
        strcpy(arrayoffilms[i],line);
        fscanf(fp,"%[\n]s",junk);
        i++;
    }
    fclose(fp);
    printf("%s\n\n\n",arrayoffilms[i]);
    return 0;
}
4

3 に答える 3

1

feof実際の読み取りが試行され、EOFに達するまで、trueは返されません。読み取りの試行には通常、失敗を示す戻り値があります。代わりにそれらを使用してみませんか?

%[%sフォーマット指定子を混同しないでください。;%[のスキャンセットを提供しません。scanfに「1つ以上の非「\n」文字の後に「s」文字が続く」を読み取るように指示します。それは理にかなっていますか?よく考えてください。このフォーマット指定子の目的は何ですか?ユーザーがEnterキーを押すだけで、scanfが「1つ以上の非'\ n'文字」を取得しない場合はどうなりますか?'\ n'以外の文字を探す前に、'\n'文字を取り除くことが重要です。フォーマット文字列に空白文字が含まれていると、scanfは最初の非空白文字まで可能な限り多くの空白を消費します。私はあなたが望んでいた、あるいはおそらく、ラインのオーバーフローを防ぐだろうと推測するつもりです。%s%[^\n]s%[^\n]%99[^\n]

おそらく、scanfによって処理されたバイト数もカウントしたいのでmalloc、正しい長さでarrayoffilmsにコピーできますが、何らかの理由で私には想像できません。%nscanfが処理したバイト数を示すフォーマット指定子を使用できます。

行の残りを読んで破棄したいことに気づきました。私の例では、改行が検出される前に99文字が読み取られた場合にのみ、行の残りの部分が破棄されます。割り当て抑制'*'を使用します:%*[^\n]

これらのフォーマット指定子を組み合わせると、フォーマット文字列" %99[^\n]%n%*[^\n]"、2つの引数(char *for%[int *for %n)、および期待される戻り値1(1つの入力が割り当てられているため)になります。戻り値が1でない場合、ループは終了します。これは、「eofを超えて読み取る」などのエラーが原因である可能性があります。

int length;
while (fscanf(fp, " %99[^\n]%n%*[^\n]", line, &length) == 1) {
    arrayoffilms[i] = malloc(length + 1);
    strcpy(arrayoffilms[i], line);
    i++;
}
于 2013-03-08T00:37:21.917 に答える
0

問題はについてである可能性がありますfeofwhileファイルの終わりに達したとき、つまり、を使用して何も取得できないときに、ループを終了する必要がありますfscanf

あなたは以下のコードに行くことができます:

 while(fscanf(fp,"%[^\n]s",line)) {
    strcpy(arrayoffilms[i],line);
    fscanf(fp,"%[\n]s",junk);
    i++;
 }

また、ファイルポインタに関連するエラーチェックは絶対に必要であり、良い習慣です。あなたは間違いなくそれを使いたいでしょう:

fp=fopen("filmtitles.txt","r");
if(fp == NULL)  /* error handling */
    printf("Could not open file: filename\n"); 
else{
/* do stuff */
}
于 2013-03-07T22:21:09.800 に答える
0

同様のことがfgets()でも発生するため、使用しないと言う人もいます。あなたが言うなら、このようにそれを見てください

while (!feof(ipf)) {

feof()がtrueになるまでに、ファイルの終わりに到達しました。読み取ったバイトはガベージであり、おそらくNULLです。使用しないでください。これは機能します:

while (!feof(ipf)) {
  if (!feof(ipf)) {
    ch = fgetc(ipf);

また、fgets()でも機能します。私は、この方法で何年も使用しています。これがPascal(またはおそらくPerl)であり、それが機能する「まで」を読んだ場合、それはテスト前の問題とテスト後の問題です。したがって、2回テストします。

于 2018-06-24T01:34:05.797 に答える