我想扫描一条线直到按下换行符。我知道gets()
函数,但我想用scanf()
来学习它。问题是,我的程序陷入无限循环,它会扫描用户的输入,然后无限地打印出来,每次扫描后应该打印一次。任何人都能解释为什么它会像这样吗?
#include<stdio.h>
int main()
{
char str[100];
while(str[0]!='\0')
{
scanf("%[^\n]",str);
printf("%s\n",str);
}
}
答案 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;
}