1

私はLinuxボックスを持っています。

この Linux ボックスには、プログラムがあります。

このプログラムには、次のようなループがあります。

int num=*"what num needs to be"*;
char proc[num];

int result;
while (1) {
result=scanf("%[^'&']%s",proc);
printf("And proc is: %s\n",proc);
printf("Result counter was: %i\n",result)
if (result == 0) break;
}

scanf("%[^'&'],%s",proc)
printf("post lop result is: %s", proc);

ご想像のとおり、stdin には「&」文字で区切られたデータが含まれています。

私が推測したよりも熟練した誰かを期待しているので、出力は次のようになります。

And proc is: *first delineated section*
Result counter was: 1
And proc is: *first delineated section*
Result counter was: 0
post loop result is: *first delineated section*

scanf は、すでに読み取った stdin の一部を消費することになっていると思いました。なぜこれをしないのですか?

また、参考までに、これは非常に安価で遅いサーバーで実行されています。ボリュームがわずかになる場合とそうでない場合があります。したがって、効率はプラスです。私はオープンですが、誰かが私にこれを提案するかもしれません....

ありがとう!

4

2 に答える 2

2

scanset には 2 つの一重引用符は必要ありません — 一重引用符で区切りたい場合は 1 つで十分ですが、 だけで止めたいと思われ&ます。以下のコードもそれを前提としています。最初の&まで読んだら、 を読むためのコードが必要です&scanf()返されたデータを使用する前に、 の結果を確認する必要があります。

したがって:

int num = 100;
char proc[num];

int result;
while ((result = scanf("%99[^&]", proc)) == 1)
{
    printf("And proc is: <<%s>>\n", proc);
    printf("Result counter was: %i\n", result);
    int c;
    while ((c = getchar()) != EOF && c != '&')
        ;
}

また、改行がフィールドの終わりをマークするかどうかも決定する必要があります...そうであれば、次のようになります。

int num = 100;
char proc[num];

int result;
while ((result = scanf("%99[^&\n]", proc)) == 1)
{
    printf("And proc is: <<%s>>\n", proc);
    printf("Result counter was: %i\n", result);
    int c;
    while ((c = getchar()) != EOF)
    {
        if (c != '&' && c != '\n')
        {
            ungetc(c, stdin);
            break;
        }
    }
}

%99[...]バッファ オーバーフローを防ぐために を使用することに注意してください。山かっこ<<%s>>は単に文字列の開始と終了を示します。たとえば、末尾の空白やタブを表示します。

このコードは、コード ブロックの途中で変数を宣言できる C99 コンパイラがあることを前提としています。そうでない場合はint c;、ループの先頭に移動します

于 2013-06-12T20:55:54.730 に答える
0

問題は、2 回目の繰り返しで、scanf が指定した形式を読み取ることができず (標準入力から読み取った行が一致しない)、proc を変更しないことです。それが 0 を返す理由でもあります: 0 個のフィールドを正常に読み取った (したがって変更した)。

于 2013-06-12T20:53:12.757 に答える