这应该很简单,但是我无法从键盘读取连续输入。
以下是代码:
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
scanf ("%s", string);
printf ("%s", string);
printf ("\nwrite a character: ");
scanf ("%c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
发生了什么
当我输入一个字符串(例如:计算机)时,程序会读取换行符('\n'
)并将其放入character
。以下是显示的外观:
write something: computer
computer
Character:
Correspondent number: 10
此外,该程序不适用于包含多个单词的字符串。 我怎么能克服这些问题?
答案 0 :(得分:9)
首先scanf
读取输入的字符串并在输入缓冲区中留下\n
。下次致电scanf
,请阅读\n
并将其存储到character
试试这个
scanf (" %c", &characte);
// ^A space before %c in scanf can skip any number of white space characters.
程序不适用于多个字符串的字符串,因为scanf
一旦找到空格字符就会停止读取。您可以使用fgets
代替
fgets(string, 200, stdin);
答案 1 :(得分:5)
OP的第一个问题通常是通过在格式前加一个空格来解决的。这将占用空白区域,包括前一行的'\n'
。
// scanf("%c", &character);
scanf(" %c", &character);
此外,该程序不适用于包含多个单词的字符串。我怎么能克服这些问题?
对于第二个问题,让我们更准确地理解“字符串”和"%s"
的作用。
string 是由第一个空字符终止并包含第一个空字符的连续字符序列。 7.1.1 1
即使报告“我输入一个字符串(例如:计算机)”,OP也没有输入字符串。 OP正在输入一行文字。 8个字符“computer”后跟 Enter 。这里没有“空字符”。取而代之的是9 char
"computer\n"
。
"%s"
中的{p> scanf("%s", string);
做了三件事:
1)扫描,但不保存任何前导空格。
2)扫描并保存到string
任意数量的非空白区域。
3)到达空白区域或EOF时停止扫描。那个char
只能回到stdin
。 '\0'
附加string
,使char
数组成为C 字符串。
要阅读包含空格的行,请不要使用scanf("%s",...
。考虑fgets()
。
fgets(string, sizeof string, stdin);
// remove potential trailing \r\n as needed
string[strcspn(string, "\n")] = 0;
混合scanf()
和fgets()
是一个问题,因为scanf("%s", string); fgets(...)
之类的调用会让'\n'
stdin
中的fgets()
作为一行读取仅由"\n"
组成。建议使用fgets()
(或* nix系统上的getline()
)读取所有用户输入。 然后解析读取的行。
fgets(string, sizeof string, stdin);
scanf(string, "%c", &character);
如果代码必须用户scanf()
来读取包含空格的用户输入:
scanf("%*[\n]"); // read any number of \n and not save.
// Read up to 199 `char`, none of which are \n
if (scanf("%199[^\n]", string) != 1) Handle_EOF();
最后,代码应该使用错误检查和输入宽度限制。测试所有输入函数的返回值。
答案 2 :(得分:3)
您所看到的是您所调用的功能的正确行为:
scanf将从输入中读取一个字,并在输入的字后立即保留输入指针。如果您键入computer<RETURN>
,则要读取的下一个字符是换行符。
要阅读整行,包括最终换行符,请使用fgets
。仔细阅读文档:fgets
返回一个字符串,其中包含它读取的最终换行符。 (gets
,由于多种原因无论如何都不应该使用,会读取并丢弃最终换行符。)
我应该补充一点,scanf
有其用途,交互式使用它会导致非常混淆行为,正如我认为你发现的那样。即使在您想要逐字阅读的情况下,如果预期用途是交互式的,也可以使用其他方法。
答案 3 :(得分:0)
您可以使用%*c
:
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
scanf ("%s%*c", string);
printf ("%s", string);
printf ("\nwrite a character: ");
scanf ("%c%*c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
%*c
将接受并忽略换行符或任何空格
答案 4 :(得分:0)
您也将getchar()
放在scanf
行之后。它将完成这项工作:)
答案 5 :(得分:-1)
需要刷新流。执行连续输入时,标准输入流stdin缓冲键盘上的每次按键。所以,当你输入&#34;计算机&#34;并按下回车键,输入流也吸收了换行,即使只有字符串&#34;计算机&#34;被分配到string
。因此,当您稍后扫描某个字符时,已加载的新行字符是扫描并分配给character
的字符。
还需要刷新stdout流。考虑一下:
...
printf("foo");
while(1)
{}
...
如果尝试执行类似这样的操作,则控制台上不会显示任何内容。系统缓冲了stdout
流,标准输出流,不知道接下来会遇到无限循环的事实,一旦发生这种情况,它就永远不会有机会将流卸载到控制台。
显然,只要scanf
阻塞程序并等待stdin
(标准输入流),它就会以类似的方式影响其他缓冲流。无论如何,无论如何,如果事情开始笨拙,最好能够正确地冲洗流。
以下对代码的修改似乎产生了所需的输出
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
fflush(stdout);
scanf ("%s", string);
fflush(stdin);
printf ("%s", string);
printf ("\nwrite a character: ");
fflush(stdout);
scanf ("%c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
输出:
写点东西:电脑
计算机
写一个字符:a
字符对应号码:97