在C语言中:
我正在尝试使用scanf
从用户获取字符,但运行程序时它不等待用户输入任何内容...
这是代码:
char ch;
printf("Enter one char");
scanf("%c", &ch);
printf("%c\n",ch);
为什么它不起作用?
%c
转换说明符不会自动跳过任何前导空格,因此如果输入流中有任何杂散的换行符(例如来自先前输入的条目),则scanf
调用将立即将其消耗掉。
解决这个问题的一种方法是在格式字符串中在转换说明符之前放置一个空格:
scanf(" %c", &c);
在格式字符串中的空格会告诉 scanf
跳过前导空格,而第一个非空白字符将由 %c
转换说明符读入。
scanf()
。使用它是不值得的痛苦。scanf()
中使用空格字符将忽略输入流中剩余的任意数量的空格字符,如果您需要读取更多的输入,怎么办?考虑以下情况:#include <stdio.h>
int main(void)
{
char ch1, ch2;
scanf("%c", &ch1); /* Leaves the newline in the input */
scanf(" %c", &ch2); /* The leading whitespace ensures it's the
previous newline is ignored */
printf("ch1: %c, ch2: %c\n", ch1, ch2);
/* All good so far */
char ch3;
scanf("%c", &ch3); /* Doesn't read input due to the same problem */
printf("ch3: %c\n", ch3);
return 0;
}
虽然第3个scanf()可以通过在前面加一个空格来解决,但并不总是像上面那样简单。
另一个主要问题是,scanf()
如果输入不符合格式,则不会丢弃输入流中的任何内容。例如,如果您为像scanf("%d", &int_var);
这样的int
输入了abc
,那么必须读取并丢弃abc
。请考虑:
#include <stdio.h>
int main(void)
{
int i;
while(1) {
if (scanf("%d", &i) != 1) { /* Input "abc" */
printf("Invalid input. Try again\n");
} else {
break;
}
}
printf("Int read: %d\n", i);
return 0;
}
另一个常见的问题是混合使用scanf()
和fgets()
。请考虑以下代码:
#include <stdio.h>
int main(void)
{
int age;
char name[256];
printf("Input your age:");
scanf("%d", &age); /* Input 10 */
printf("Input your full name [firstname lastname]");
fgets(name, sizeof name, stdin); /* Doesn't read! */
return 0;
}
由于上一次 scanf() 调用留下的换行符被读取,所以调用 fgets()
不会等待输入。当遇到换行符时,fgets()
终止输入读取。
scanf()
存在许多类似的问题。这就是为什么通常建议避免使用它的原因。
那么,有什么替代方法吗?请使用以下方式使用fgets()
函数来读取单个字符:
#include <stdio.h>
int main(void)
{
char line[256];
char ch;
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
ch = line[0];
printf("Character read: %c\n", ch);
return 0;
}
使用 fgets()
时需要注意一点,如果输入缓冲区有足够的空间,它将读入换行符。 如果不希望出现此情况,则可以将其删除:
char line[256];
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
line[strcpsn(line, "\n")] = 0; /* removes the trailing newline, if present */
我想分享一个类似的事情,
在使用Visual Studio时可能会遇到以下错误:
'scanf':函数或变量可能不安全。考虑改用
scanf_s
。要禁用过时警告,请使用_CRT_SECURE_NO_WARNINGS
为了避免这种情况,您应该按照以下格式编写代码:
读入单个字符的代码示例如下:
char c;
scanf_s("%c", &c, 1);
当读取非空结尾字符串的多个字符时,使用整数作为宽度规范和缓冲区大小。
char c[4];
scanf_s("%4c", &c, _countof(c));
return 0;
} - Besuglov Sergey无论是fgets还是getchar都不能解决这个问题。唯一的解决办法是在使用scanf时,在%c之前保留一个空格。
以下示例中,即使使用fgets也不起作用。
scanf(" %c",ch); //可以正常工作
char line[256];
char ch;
int i;
printf("Enter a num : ");
scanf("%d",&i);
printf("Enter a char : ");
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
ch = line[0];
printf("Character read: %c\n", ch);
对我有效的唯一代码是:
scanf(" %c",&c);
我也遇到了同样的问题,只有单个字符有这个问题。经过一个小时的随机测试,我还没有报告任何问题。人们会认为C语言现在应该有一种防弹函数来从键盘中检索单个字符,而不是一堆可能的变通方法...只是说说而已...
尝试使用 getchar(); 替代
语法:
void main() {
char ch;
ch = getchar();
}
fflush(stdin);
以清除缓冲区。fflush(stdin);
是未定义行为。 - P.Pfflush(stdin)
是 UB,在许多 SO 的问题中提到。 - danglingpointerchar c[10];
scanf ("%s", c);
我相信它工作得很好。
scanf
函数读取_单个字符_,而不是一串字符。 - ForceBru在%c转换说明符之前提供一个空格,以便编译器忽略空格。程序可以编写如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char ch;
printf("Enter one char");
scanf(" %c", &ch); /*Space is given before %c*/
printf("%c\n",ch);
return 0;
}