c -扫描输入的字符工作一次,然后是空白



我想在我编写的代码中引用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]; to char q1;
  • change scanf("%s",q1); to scanf(" %c", &q1);
  • if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0)更改为if((q1 =='Y') || q1 == 'y')

话虽如此,作为提示,

  1. main()推荐签名为int main(void)
  2. 为了避免较长的输入导致缓冲区溢出的可能性,最好使用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 q1scanf("%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的回车键,因为按回车键也会向流发送一个键。

相关内容

  • 没有找到相关文章

最新更新