我想在我编写的代码中引用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 startedn", name);
endgame:
getchar();
return 0;
}
条目"Nick"的输出为:
嗨,Nick,你想找点乐子吗?
棒极了,让我们来玩一下
我们开始吧
我希望它说:
Nick,我们开始吧。
但是由于某些原因char name
在第一次正确使用后是空白的
问题,(,我认为正确)是与char q1[1];
,然后使用它像
scanf("%s",q1);
这会导致内存边界溢出,因为单字符数组不足以容纳只有一个元素的字符串,因为它缺乏字符串所需的空结束符的空间。这将调用未定义的行为。
相反,- change
char q1[1];
tochar q1;
- change
scanf("%s",q1);
toscanf(" %c", &q1);
- 将
if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0)
更改为if((q1 =='Y') || q1 == 'y')
话虽如此,作为提示,
-
main()
推荐签名为int main(void)
。 为了避免较长的输入导致缓冲区溢出的可能性,最好使用
scanf()
限制输入的长度,如scanf("%49s", name);
扩展q1
缓冲区的大小。scanf("%s", q1)
没有足够的空间来存储输入。记住,C使用空字符' '
来终止字符串。如果不考虑这一点,缓冲区可能会溢出到其他内存中,导致未定义的行为。在本例中,它可能覆盖了分配给name
的内存,因此name
最终指向" ick"。这会导致printf(%s)
(查找' '
以知道何时停止打印)认为字符串比实际长度短。
如果扩展缓冲区,代码将完美地工作:
#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 startedn", 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)
来完全避免对另一个字符串的需要(注意"地址"操作符,因为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 startedn", 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 startedn", name);
getchar();
return 0;
}
如果你走这条路,你必须忽略使用格式说明符%*c
的回车键,因为按回车键也会向流发送一个键。