-3

K&R (ex 1-17) のエクササイズを試していて、独自の解決策を思いつきました。問題は、おそらく無限ループでプログラムがハングしているように見えることです。NUL ('\0') 文字の挿入を省略したのは、C が一般に文字列の末尾に自動的に付加することがわかったからです (そうではありませんか?)。

誰かが何が間違っているかを見つけるのを手伝ってもらえますか?

Win8(x64)でCygwinでGCCコンパイラを使用しています..

質問 - 80 文字を超えるすべての入力行を出力してください

#include<stdio.h>

#define MINLEN 80
#define MAXLEN 1000

/* getlin : inputs the string and returns its length */
int getlin(char line[])
{
    int c,index;

    for(index = 0 ; (c != '\n') && ((c = getchar()) != EOF) && (index < MAXLEN) ; index++)
        line[index] = c;

    return (index);                                                                     // Returns length of the input string
}

main()
{
    int len;
    char chArr[MAXLEN];

    while((len = getlin(chArr))>0)
    {
        /* A printf here,(which I had originally inserted for debugging purposes) Miraculously solves the problem!!*/
        if(len>=MINLEN)
            printf("\n%s",chArr);
    }
    return 0;
}
4

4 に答える 4

3

また、C では通常、null('\0') 文字の挿入が自動的に文字列の末尾に追加されることがわかったため、省略しました (そうではありませんか?)。

いいえ、そうではありません。getchar()入力文字を 1 つずつ読み取るために使用しています。文字を自分で配列に入れる場合は、自分で終了する必要があります。

文字列を返す C 関数は通常、文字列を終了しますが、ここで行っているのはそれではありません。

あなたの入力ループは少し奇妙です。論理 AND 演算子は、左側が false と評価された場合にのみ右側を実行します (これを「ショートサーキット」と呼びます)。ループ内のテストの順序を並べ替えると役立ちます。

for(index = 0 ; (index < MAXLEN) && ((c = getchar()) != EOF) && (c != '\n'); index++)
    line[index] = c;

このようにして、コンテンツのテストを実行する前にcから値を受け取ります。getchar()

于 2013-09-05T06:58:18.390 に答える
1

1) C は文字列にファイナルを追加しません\0。少なくとも 81 文字の配列を使用し\0、最後に記述した文字の後に最終文字を配置する責任があります。

c2)読む前にの値をテストしている

3) printf は送信時にフラッシュされる I/O 用のバッファを使用するため、プログラムは何も出力しません\n。このステートメントを変更して、 final を出力します\n

printf("\n%s",chArr);

なる:

printf("%s\n",chArr);

4) EOF をプログラムに送信するには、Ctrl+DUNIX で行う必要があります。Windows で可能かどうかはわかりません。これが、プログラムが終了しない理由である可能性があります。

于 2013-09-05T07:01:19.887 に答える
1

何が問題なのかはわかりませんが、プログラムに入力を提供していないので、推測しています。

私の推測では、getlin で変数 c が '\n' に設定され、その時点で別の文字が取得されることはありません。戻ってループし続けるだけです。

テストする前に getlin 関数内の何かに c を決して設定しないことが問題です。

于 2013-09-05T07:01:39.977 に答える
1

C は、文字列の末尾に NUL ターミネータを自動的に挿入しません。一部の関数はそうする場合があります (snprintf など)。ドキュメントを参照してください。cさらに、のようにすべての変数を初期化するように注意してくださいgetlin()

于 2013-09-05T07:01:50.657 に答える