为什么我的程序进入无限循环?

时间:2016-12-08 16:54:03

标签: c string while-loop scanf infinite-loop

我想扫描一条线直到按下换行符。我知道gets()函数,但我想用scanf()来学习它。问题是,我的程序陷入无限循环,它会扫描用户的输入,然后无限地打印出来,每次扫描后应该打印一次。任何人都能解释为什么它会像这样吗?

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

3 个答案:

答案 0 :(得分:3)

如果您坚持使用scanf,请更改格式说明符:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="unread">
  <span class="text">span</span>
  <span class="text">span</span>
  <span class="text">span</span>
</div>
<div class="unread">
  <span class="text">span</span>
  <span class="text">span</span>
  <span class="text">span</span>
</div>
<div class="unread">
  <span class="text">span</span>
  <span class="text">span</span>
  <span class="text">span</span>
</div>

前面的空间将跳过任何先前的&#34;悬挂&#34; \ n

此外,您应该在检查str内容之前对其进行初始化,最好使用" %[^\n]"

这样的事情应该有效

do-while-loop

我个人更喜欢将char str[100] = {0}; do { scanf(" %[^\n]",str); printf("%s\n",str); } while(str[0]!='q'); fgets(...)结合使用 另外,最好检查scanf的返回值,有一个返回值。

添加另一个条件,循环直到&#34; q&#34;或&#34;退出&#34;

答案 1 :(得分:1)

由于%[^\n]不接受换行符,因此在第二个循环中不接受输入。

也许,这会做你想要的。

#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);
    }
}

答案 2 :(得分:0)

BLUEPIXY绝对正确。 scanf()的第一次返回是将\n留在输入缓冲区中。随后的scanf()来电将立即返回,而不会读取stdin中的任何字符,因为scanf()会停止在\n上阅读。所以循环随之而来。避免循环的一种方法是在调用\n后从输入中读取scanf(),如下所示:

#include <stdio.h>

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

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

你似乎对输入的工作方式存在一些错误的信念。所以我将在下面解释。

您不需要在循环中执行此操作,因为scanf()在您指定字符串格式时不会一次读取并返回一个字符。终端输入为buffered。当您要求scanf()返回字符串时,终端只会在收到scanf()时将输入字符串发送到newline。发生这种情况时scanf()会返回不带newline的字符串。

您需要做额外的工作来关闭终端线缓冲。以下示例代码显示了如何关闭终端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;
}