getchar() 的意外输出
unexpected output with getchar()
char c = ' ';
while(c != 'x')
{
c = getchar();
printf("threadFuncParam = %u\n", threadFuncParam);
}
在上面的代码片段中,每次我输入一个字符时,打印都会打印两次 threadFuncParam 值,而我希望它只打印一次。
根据我的理解,它第一次进入时条件为真,然后在 getchar 调用中等待用户输入输入字符,它将打印该值,然后如果输入字符不是 x,它将在 getchar 调用中等待另一个输入,但每当我输入一个字符时,我都会为每个输入看到 2 个打印离子屏幕。我无法理解为什么?
我想在这里做的是,在主线程中,我从用户那里获取单个字符输入,而在工作线程中,我正在递增一个每秒递增的计数器,每次用户输入一个字符时,我都会打印该值输入直到用户输入 'x' 个字符。
我认为问题在于应用逻辑的方式。在检查条件之前打印 。 请参阅此以获取解释:
循环 1:执行 getchar() 表示值 'a'。
printf() 已执行。
循环 2:因为 c='a',条件为真。现在,getchar() 以 'x' 值执行。
printf() 再次执行。
循环 3:条件被评估为 false。循环终止。
所以基本上你应该稍微改变一下你的逻辑。
这里的简单问题是控制台(输入)仅在遇到回车键或 ctr+d
.
时才将文本发送到 stdin
因此,额外的 \n
进入您的输入流。这会导致您的程序在下一次迭代中读取该字符。
一个简单的解决方案是读取流中的所有白色 space 字符。
这可以通过多种方式完成 -
如果需要丢弃任何白色space字符(包括space、制表符、vtabs、换行符),可以添加
scanf(" ");
在getchar();
之前
如果您只需要丢弃因按回车键而出现的换行符,您可以添加
scanf("%*[\n]")
在getchar();
之前
这将吃掉下一个字符之前的所有 \n
。但是不会吃spaces.
最后如果你只想丢弃 1 \n
你可以做到
scanf("%*1[\n]");
记住 但是,在所有情况下,scanf
应该紧接在 getchar()
之前,因为 scanf
会等到它找到下一个非白色 space 字符。
所有案例都是在@chux 的评论帮助下解决的。
如果您尝试调试您的程序(这是学习编码的最佳方式),您会发现第二个值每次都是 10
。在 ASCII table 中,您会发现这是换行代码。您在每个字符之后按的是哪个。然后通过快速简单的搜索,您会找到这个 THREAD。描述的问题在哪里,你很容易解决。
char c = ' ';
while(c != 'x')
{
printf("threadFuncParam = %u\n", (char)c);
fflush(stdout);
if (scanf(" %c",&c) != 1)
{
// failed
}
}
char c = ' ';
while(c != 'x')
{
c = getchar();
printf("threadFuncParam = %u\n", threadFuncParam);
}
在上面的代码片段中,每次我输入一个字符时,打印都会打印两次 threadFuncParam 值,而我希望它只打印一次。 根据我的理解,它第一次进入时条件为真,然后在 getchar 调用中等待用户输入输入字符,它将打印该值,然后如果输入字符不是 x,它将在 getchar 调用中等待另一个输入,但每当我输入一个字符时,我都会为每个输入看到 2 个打印离子屏幕。我无法理解为什么?
我想在这里做的是,在主线程中,我从用户那里获取单个字符输入,而在工作线程中,我正在递增一个每秒递增的计数器,每次用户输入一个字符时,我都会打印该值输入直到用户输入 'x' 个字符。
我认为问题在于应用逻辑的方式。在检查条件之前打印 。 请参阅此以获取解释:
循环 1:执行 getchar() 表示值 'a'。
printf() 已执行。
循环 2:因为 c='a',条件为真。现在,getchar() 以 'x' 值执行。
printf() 再次执行。
循环 3:条件被评估为 false。循环终止。
所以基本上你应该稍微改变一下你的逻辑。
这里的简单问题是控制台(输入)仅在遇到回车键或 ctr+d
.
stdin
因此,额外的 \n
进入您的输入流。这会导致您的程序在下一次迭代中读取该字符。
一个简单的解决方案是读取流中的所有白色 space 字符。
这可以通过多种方式完成 -
如果需要丢弃任何白色space字符(包括space、制表符、vtabs、换行符),可以添加
scanf(" ");
在getchar();
如果您只需要丢弃因按回车键而出现的换行符,您可以添加
scanf("%*[\n]")
在getchar();
这将吃掉下一个字符之前的所有 \n
。但是不会吃spaces.
最后如果你只想丢弃 1 \n
你可以做到
scanf("%*1[\n]");
记住 但是,在所有情况下,scanf
应该紧接在 getchar()
之前,因为 scanf
会等到它找到下一个非白色 space 字符。
所有案例都是在@chux 的评论帮助下解决的。
如果您尝试调试您的程序(这是学习编码的最佳方式),您会发现第二个值每次都是 10
。在 ASCII table 中,您会发现这是换行代码。您在每个字符之后按的是哪个。然后通过快速简单的搜索,您会找到这个 THREAD。描述的问题在哪里,你很容易解决。
char c = ' ';
while(c != 'x')
{
printf("threadFuncParam = %u\n", (char)c);
fflush(stdout);
if (scanf(" %c",&c) != 1)
{
// failed
}
}