所以我的代码执行以下操作:
这是我的主要代码
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();
}
这是yesnochecker函数:
int yesnochecker()
{
char yesorno;
printf("Do you want to continue? (Y/N)");
while(scanf("%s",&yesorno))
{
if(yesorno=='Y')
return 1;
if(yesorno='N')
return 0;
printf("*Wrong input. Please reenter (Y/N): ");
}
}
因此在dev C ++上,我的代码无法正确运行。完成选项1后,当我输入“ Y”然后选择选项2时,情况2将显示一些奇怪的数字。但是,它在联机C编译器上运行良好。
然后,当我将yesnochecker()函数中的char yesorno
更改为char yesorno[2]
并将其视为字符串时,代码确实起作用。
有人可以照亮吗?
答案 0 :(得分:1)
用char c
读scanf("%s", &c);
是个坏主意。 "%s"
需要一个缓冲区来存储字符串。适用于char
的唯一字符串是一个空字符串(仅由终结符'\0'
组成-不太有用)。每个包含1个字符的字符串都需要2 char
的存储空间-1个字符,1个终止符('\0'
)。提供char
用于存储是Undefined Behavior。
因此,第一个提示是改用正确的格式化程序– "%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;
}
输出:
Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n):
Input '
'
Continue (y/n): n↵
Input 'n'
是什么?
scanf("%c")
从输入中消耗一个字符。另一个字符(为 ENTER 键插入)保留在输入缓冲区中,直到下一次调用任何输入函数为止。
太糟糕了,如果没有 ENTER ,则很难在控制台上确认输入。
一个可能的解决方案是读取字符,直到接收到 ENTER 键(或由于任何原因输入失败)。 (顺便说一句,getc()
或fgetc()
也可以用来读取单个字符。):
#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;
}
输出:
Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n): Hello↵
Input 'H'
Continue (y/n): n↵
Input 'n'
请注意,我将读取字符的类型更改为int
。这是因为getc()
/ fgetc()
返回的int
可以存储256个可能的char
值中的任何一个,以及返回的-1
失败的原因。
但是,将int
与字符常量(例如'y'
)进行比较并不是什么问题。在C语言中,字符常量的类型仅为int
(SO: Type of character constant)。