2017-11-21 5 views
-1
#include <stdio.h> 
#define IN 1 
#define OUT 0 

int main() 
{ 
    while (1) 
    { 
    FILE *fptr1; 
    char filename[100]; 
    printf("Enter the filename to open for reading \n"); 
    scanf("%s", filename); 
    fptr1 = fopen(filename, "r"); 

    int c, nl, nw, nc, state; // These variables aren't being reset. 

    while ((c = fgetc(fptr1)) != EOF) 
    { 
     ++nc; 
     if (c == '\n') ++nl; 
     if (c == '\t' || c == '\n' || c == ' ') state = OUT; 
     else if (state == OUT) 
     { 
     state = IN; 
     ++nw; 
     } 
    }; 
    printf("Lines: %d Words: %d Characters: %d\n", nl, nw, nc); 
    } 
    return 0; 
} 

これは、ファイルを解析し、それが持つ線、単語、および文字の数を出力する簡単なプログラムです。新しい行、単語、文字が検出されると、nl、nw、ncがインクリメントされます。出力:6つのワード:15の文字:81whileループの各反復で変数が破棄されませんか?

を読み取るために開くためにファイル名を入力

線が

data.txtをを読み取るために開くためにファイル名を入力してください

data.txt

行:12ワード:30文字:162

たときにwhileループが終了すると、それが正しく初めて動作しますが、それは、NWをNL破壊しない

を読み取るため開くためにNCを、ファイル名を入力し、ちょうどそれらに追加し続けます。どうして?

+0

あなたの 'fclose()'はどこですか? – iBug

+0

あなたは「リセット」すべきだと思いますか?ローカル変数はそれ自体をリセットしません。それらをリセットするはずののはあなたです。そして、あなたはそれをやっていません。初期化されていない変数には、予測できない値が含まれています。これらの予測不可能な値は、以前の反復の値である可能性があります。または、他の何か。 – AnT

+0

Heh。おそらく、彼はJavaからの変換であり、初期化がゼロになっているかもしれません。 – Gene

答えて

1

未定義の変数にアクセスして未定義の動作を呼び出しています。

それぞれの反復で、新しい変数セットが得られます。つまり、以前の反復の変数値に頼ることはできません。

int c, nl = 0, nw = 0, nc = 0, state = OUT; 

少数の他のノートscanf("%99s",filename);scanfを変更します。

作業が完了したら、ファイルを閉じます。そうしないと、ファイルを閉じずにたくさんのファイルを使用すると、リソースが足りなくなる可能性があります。あなたはそれがプロセスを終了時にクローズされますが、まだあなたが使用するリソースの割り当てを解除するには良い習慣です、それを閉じていない場合でも、この場合

flocse(fptr1);

。それは 良い練習です。

+2

"*それは良い習慣です*"それは実際には、食べ物のようなもので、皿を洗うものではありません。それは問題に見えませんが、それはとても迷惑です! –

1

あなたは右、おそらく彼らの宣言の後に、それらをすべて

nl = nw = nc = state = 0; 

を初期化する必要があり、それが今まで働いていたことを「ラッキー」でした。重要なことは、内側のwhileループの前に初期化する必要があることです。

0

これらの変数はリセットされません。あなたはこのように、それらを使用する前に手動でリセットする必要がwhileループの各反復で

:また

c = 0; 
nl = 0; 
nw = 0; 
nc = 0; 
state = OUT; 

、あなたはループの反復ごとに開いているファイルを閉じてください -

fclose(fptr1); 
0

コードはクラッシュしないことが幸運だから機能します。値を初期化したことがないので、各ループで値は不確定にリセットされます。幸いにもそれらは最後のループからの単なる値ですが、はこれを誰も保証しません

また、あなたのファイルハンドルを決して閉じたことがない可能性があります。fclose(fptr1)。いくつかのループの中で、破損したファイルを取得したり、それ以上のファイルを開けなかったりすることがあります。

0

このコードにはいくつかの問題があります。 まず、すべてのカウンタには初期値がありません。 nl, nw, nc, and stateは、内部ループが開始する前に任意の値を持つことができます。それらはスタックに割り当てられ、 'c'言語はそれらを初期化しません。あなたは本当に初めてそれが働いたことは本当に幸運でした。したがって、他の回答をintに示すように、それらを '0'に初期化する必要があります。

しかし、そこにはさらに問題があります。まず、scanfは入力のサイズをチェックしません。ファイル名の長さは100より長くすることはできないと仮定しましたが、実際には必ずしも真ではありません。したがって、%99sなどを使用して、配列がオーバーフローしていないことを確認する必要があります。

第二に、あなたが最初のLOPの先頭にファイルを開き、それを閉じたことがない、あなたがリソースを解放するために、ループの最後で、それを実行する必要があり、そうでなければ、開かれたファイルに対して、すべてのシステムリソースを使用することを危険にさらします。

関連する問題