我想在我编写的代码中引用name
的输入,但由于某些原因我在第一个printf()
中成功使用它后,第二个printf()
无法打印这个名字。
int main()
{
char name[50];
char q1[1];
printf( " What is your name?\n");
scanf("%s", name);
printf( " Hi %s, Do you want to have some fun? [Y/N]\n",name);
scanf("%s",q1);
if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0)
{
printf("Awesome, let's play!\n");
}
else
{
printf("Fine"); goto endgame;
}
printf( "So %s, it's time to get started\n", name);
endgame:
getchar();
return 0;
}
条目的输出'尼克'是:
你好尼克,你想要玩得开心吗?很棒的让我玩耍所以, 让我们开始吧
我希望它能说:
所以尼克,让我们开始吧。
但由于某些原因,第一次正确使用后,char name
为空。
答案 0 :(得分:4)
问题,(我假设正确)是char q1[1];
然后使用
scanf("%s",q1);
它导致内存边界溢出,因为一个char字符数组不足以容纳只有一个元素的字符串,因为它缺少空间终止符所需的空间。 字符串。这会调用undefined behaviour。
相反,
char q1[1];
更改为char q1;
scanf("%s",q1);
更改为scanf(" %c", &q1);
if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0)
更改为if((q1 =='Y') || q1 == 'y')
那说,作为一个说明,
main()
的推荐签名为int main(void)
。为了避免更长输入缓冲区溢出的可能性,最好通过写入<{1}}来限制输入的长度{ / p>
scanf()
答案 1 :(得分:2)
扩展q1
缓冲区的大小。 scanf("%s", q1)
没有足够的空间存储输入内容。请记住,C使用空字符'\0'
来终止字符串。如果您没有考虑到这一点,缓冲区可能会溢出到导致undefined behavior的其他内存中。在这种情况下,它可能会覆盖分配给name
的内存,因此name
最终会指向&#34; \ 0ick&#34;。这导致printf(%s)
查找'\0'
知道何时停止打印,认为字符串比实际更短。
如果扩展缓冲区,代码可以正常工作:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char name[50];
char q1[50];
printf( " What is your name?\n");
scanf("%49s", name);
printf( " Hi %s, Do you want to have some fun? [Y/N]\n",name);
scanf("%49s",q1);
if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0)
{
printf("Awesome, let's play!\n");
}
else
{
printf("Fine");
}
printf( "So %s, it's time to get started\n", name);
getchar();
return 0;
}
输出:
What is your name?
Nick
Hi Nick, Do you want to have some fun? [Y/N]
y
Awesome, let's play!
So Nick, it's time to get started
请注意,我已添加限定符%49s
以避免此类缓冲区溢出。
您还可以通过将char q1[50]
和scanf("%49s")
更改为char q1
和scanf("%c%*c", &q1)
来完全避开对其他字符串的需求(请注意&#34;&#34;地址&#34 ;运算符,因为q1
不再是指针。)
你甚至可能从中获得性能提升(虽然很小),因为琴弦是臭名昭着的记忆障碍物。比较单个字符通常比比较字符串更受欢迎。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char name[50];
char q1;
printf( " What is your name?\n");
scanf("%49s%*c", name);
printf( " Hi %s, Do you want to have some fun? [Y/N]\n",name);
scanf("%c%*c",&q1);
if(q1 == 'Y' || q1 == 'y')
{
printf("Awesome, let's play!\n");
}
else
{
printf("Fine");
}
printf( "So %s, it's time to get started\n", name);
getchar();
return 0;
}
if(q1 == 'Y' || q1 == 'y')
{
printf("Awesome, let's play!\n");
}
else
{
printf("Fine");
}
printf( "So %s, it's time to get started\n", name);
getchar();
return 0;
}
如果你走这条路线,你必须使用格式说明符%*c
忽略输入键,因为按Enter键也会向流发送一个键。