2016-12-08 7 views
-1

改行が押されるまで行を走査したい。私はgets()機能を認識していますが、私はscanf()でそれを学びたかったのです。問題は、私のプログラムが無限ループに陥って、ユーザーからの入力をスキャンして無限に印刷し、スキャンごとに1回印刷する必要があることです。なぜ誰がこのように行動しているのか説明できますか?私のプログラムが無限ループになったのはなぜですか?

#include<stdio.h> 
int main() 
{ 
    char str[100]; 
    while(str[0]!='\0') 
    { 
     scanf("%[^\n]",str); 
     printf("%s\n",str); 
    } 
} 
+5

'str [0]'を初めてテストすると、初期化されません。 'scanf'は値を返します。これを使って。 –

+1

'scanf("%[^ \ n] "、文字列);' 1回目の改行が残っています。 2回目以降、拒否されます。 'str [0]!= '\ 0''も最初に、初期化変数を使用しています。 – BLUEPIXY

+1

"gets()関数を認識していますが、これは廃止されているので使用しないでください。 –

答えて

3

あなたはscanfのを使う、という場合は、フォーマット指定を変更:前の

" %[^\n]" 

スペースは、以前の「ぶら下がり」をスキップします\ nは

また、あなたはstrの配列を初期化する必要がありますその内容を確認する前に、代わりにdo-while-loopを使用してください。このような

何かが

char str[100] = {0}; 
do 
{ 
    scanf(" %[^\n]",str); 
    printf("%s\n",str); 
} 
while(str[0]!='q'); 

は個人的に私は sscanf(...) との組み合わせで fgets(...)を使用することを好む動作するはずです。また、scanf関数の戻り値をチェックすることをお勧めし、目的の戻り値があります。 「Q」または %[^\n]は改行を受け付けないので

+0

フォーマット指定子のスペースが左上に\ nを食べることを指摘してくれてありがとうございます。 – Chimera

+1

'while(str [0]!= '\ 0');'意味がありません。 – BLUEPIXY

+0

@BLUEPIXY so true/facepalm –

0

BLUEPIXYは間違いありません。 scanf()からの最初の復帰は、\nを入力バッファに残しています。その後scanf()コールは、\nでの読み取りを中止するので、stdinからの文字を読み取らずにすぐに戻ります。scanf()ループが続いています。あなたが入力がどのように機能するかについて、いくつかの偽の信念の下にあるように見える

#include <stdio.h> 

int main() 
{ 
    char str[100] = {0}; 

    do 
    { 
     scanf("%[^\n]",str); 
     getchar(); 
     printf("%s\n",str); 
    }while(str[0] != '\0'); 
} 

:以下に示すようにループを回避する1つの方法は、scanf()への呼び出し後の入力から\nを読むことです。だから私は以下で説明するつもりです。

scanf()は、文字列形式を指定するときに一度に1文字を読み込んで返さないため、ループ内でこれを行う必要はありません。入力はbufferedです。 scanf()に文字列を返すように依頼すると、端末はnewlineを受け取ったときに入力文字列をscanf()にのみ送信します。それが起こると、のない文字列が返されます。

端末回線のバッファリングをオフにするには、余分な作業が必要になります。以下のコード例は、ターミナルI/Oバッファリングをオフにする方法を示しています。

#include <stdio.h> 
#include <unistd.h> 
#include <termios.h> 

int main() 
{ 
    struct termios old_tio, new_tio; 
    unsigned char c; 

    /* get the terminal settings for stdin */ 
    tcgetattr(STDIN_FILENO,&old_tio); 

    /* we want to keep the old setting to restore them a the end */ 
    new_tio=old_tio; 

    /* disable canonical mode (buffered i/o) and local echo */ 
    new_tio.c_lflag &=(~ICANON & ~ECHO); 

    /* set the new settings immediately */ 
    tcsetattr(STDIN_FILENO,TCSANOW,&new_tio); 

    do { 
     c=getchar(); 
     printf("%c ",(char)c); 
    } while(c!='q'); 

    /* restore the former settings */ 
    tcsetattr(STDIN_FILENO,TCSANOW,&old_tio); 

    return 0; 
} 
+0

downvoteありがとうございます。私は最初の答えが実際に質問に答えなかったことを認識しています。私は私の答えが今有効であると信じています。 – Chimera

1

を「終了」までループ

は、別のwhile条件を追加し、入力が第二のループに受け入れられません。

これはおそらく、あなたが望むことをするでしょう。

#include<stdio.h> 

int main(void){ 
    char str[100]; 

    while(1== scanf("%99[^\n]%*c",str)){//%*c consumes newline. Also In case of only newline terminates the loop 
     printf("%s\n",str); 
    } 
} 
+0

とてもいいですね。あなたが%* cを指定できるかどうかわかりませんでした。驚くばかり! – Chimera

関連する問題