devC中扫描字符导致的问题
因此,我的代码执行以下操作:devC中扫描字符导致的问题,c,string,character,C,String,Character,因此,我的代码执行以下操作: 问问有什么选择 如果选项为1:扫描一些数字 如果选项为2:打印这些数字 在每个选项之后,询问用户是否要继续选择(是/否) 这是我的主要代码 while(yesnocheck==1) { printf("What's your option?: "); scanf("%d",&b); switch(b){ case 1: printf("How many numbers?: ");
while(yesnocheck==1)
{
printf("What's your option?: ");
scanf("%d",&b);
switch(b){
case 1:
printf("How many numbers?: ");
scanf(" %d",&n);
a=(struct sv*)malloc(n*sizeof(struct sv));
for(int i=0;i<n;i++)
scanf("%d",&((a+i)->num));
break;
case 2:
for(int i=0;i<n;i++)
printf("%d\n",(a+i)->num);
break;
}
yesnocheck==yesnochecker();
}
在DeV C++中,我的代码不能正确运行。完成选项1后,当我输入“Y”然后选择选项2时,案例2将显示一些奇怪的数字。然而,它在在线C编译器上运行良好
然后,当我将yesnochecker()函数中的char-yesorno
更改为char-yesorno[2]
并将其作为字符串处理时,代码确实起作用
有人能解释一下吗?用
scanf(“%s,&c”)读charc
是个坏主意代码><代码>“%s”
需要缓冲区来存储字符串。唯一适合字符的字符串是空字符串(仅由终止符'\0'
组成-不是很有用)。每个具有1个字符的字符串都需要2个char
s存储空间–1个用于字符,1个用于终止符('\0'
)。为存储提供char
,这是非常困难的
因此,第一个提示是使用正确的格式化程序–
“%c”
这会更好,因为它会删除未定义的行为。但是,它不能解决另一个问题,如以下示例所示:
#include <stdio.h>
int cont()
{
char c; do {
printf("Continue (y/n): ");
scanf("%c", &c);
printf("Input %c\n", c);
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
输出:
循环迭代1。
继续(是/否):是↵
输入“y”
循环迭代2。
继续(是/否):您好↵
输入“H”
继续(是/否):否↵
输入“n”
请注意,我将读取字符的类型更改为int
。这是因为getc()
/fgetc()
返回一个int
,它能够存储256个可能的char
值中的任何一个,以及在失败时返回的-1
但是,将
int
与字符常量(例如'y'
)进行比较没有任何问题。在C语言中,字符常量的类型就是int
()。你扫描错了。你想要的只是一个角色,对吗?scanf(“%s”,&yesorno)
中的格式化程序是%c
,而不是%s
。这里有很多编程错误。您可能可以打开警告以查看失败的位置。请注意,%s
格式需要至少包含2个字符的数组(一个用于选择,一个用于空字节),并且容易发生溢出(%1s
对于包含2个字符的数组更安全)。如果使用“%c”
,则可以使用单个字符。领先空间并非偶然;这是至关重要的。它跳过空白(例如上次输入留下的换行符)。此外,如果while条件在遇到Y或N之前遇到EOF,它将进入无限循环。欢迎使用SO。如果编译并运行char yesorno;scanf(“%s”和“yesorno”)
然后键入例如Y
,然后它存储两个字符--Y
和\0
(以终止字符串)。您的char yesorno
仅为一个提供存储,第二个被写入不属于yesorno
的内存。这是。您可以使用char yesorno;scanf(“%c”和“yesorno”)代码>或提供足够的存储空间。后者很难用“%s”
实现,因为没有给出长度限制代码>是错误的;您需要的是赋值,而不是比较。更简单的选择是使用“%c”
。前导空格跳过可选的空白,例如换行符。当用户被要求输入“y”时,如果用户倾向于输入“是”,则没有帮助。然后,一个字符吞食循环可能会有所帮助,但如果用户意外地在目标字符之前键入空格,则前导空格仍然会有所帮助。@JonathanLeffler感谢您的启示。(我从不在严肃的工作中使用scanf()
,而且很容易忘记这些细节。)不过,在输入缓冲区中留下未读字符可能会干扰单独的代码(用于单独的目的),这是我会感到不安的。顺便说一句,接受yes
而不是y
是我想说的另一件事,但我忘了提。(对于这样一个简单的话题,答案这么长,不是吗?)——)
#include <stdio.h>
int cont()
{
char c; do {
printf("Continue (y/n): ");
scanf("%c", &c);
printf("Input %c\n", c);
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
#include <stdio.h>
int cont()
{
int c;
do {
int d;
printf("Continue (y/n): ");
if ((c = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
printf("Input '%c'\n", c);
for (d = c; d != '\n';) {
if ((d = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
}
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}