gpt4 book ai didi

C、Buffer 没有按预期清除?

转载 作者:太空宇宙 更新时间:2023-11-04 01:33:13 25 4
gpt4 key购买 nike

我在理解教授给我的一些 C 代码时遇到了一些困难。代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
char name[1000];

printf( "What's your name? " );
scanf( "%s", name );
printf( "name is %s\n", name );

scanf( "%[^\n]", name ); /* read the entire line (up to but not
including the '\n' at then end) */

getchar(); /* consume the newline from the input */

printf( "name is %s\n", name );

return EXIT_SUCCESS;
}

用户输入一个名字并打印两次:

What's your name? Dan
name is Dan
name is Dan

这让我很困惑这是如何工作的。使用 printf 打印提示,使用 scanf 将输入读入缓冲区,然后使用 printf 打印缓冲区。但是,第二个 printf 中的\n 应该清除缓冲区,那么第二个 scanf 从哪里读取?我认为它会等待用户输入(给定一个空缓冲区)但它不会,它只知道名称。这是如何运作的?

最佳答案

第二个 scanf() 调用卡住了,什么也没做,因为下一个要读取的字符是 \nscanf() 不处理“空”输入,只是保持 name 缓冲区不变。由于 name 未更改,因此名称的第二个 printf() 与名称的第一个 printf() 相同。

如果您检查过 scanf() 的返回值,您会注意到第二个返回了 0,这意味着它没有扫描任何输入。

此代码使用 scanf() 的方式存在危险。由于输入说明符不会通知 scanf() 要读取多少字节,因此输入可能会溢出 name 缓冲区。这可能会导致未定义的行为,在最坏的情况下,会被用于堆栈粉碎攻击。您可以通过通知 scanf() 不要扫描太多字节来防止出现此问题:

    scanf( "%999s", name );

scanf( "%999[^\n]", name );

长度必须在 scanf() 的格式字符串中拼写出来,无法将此信息作为变量参数中的参数提供。通常认为使用 fgets() 处理用户输入,然后使用 sscanf() 解析它更可靠。

    /* get the name */
char input[sizeof(name)];
input[sizeof(input)-2] = '\n'
if ( fgets( input, sizeof(input), stdin ) != 0 ) {
if ( sscanf( "%s", name ) == 0 ) name[0] = '\0';
}

/* get the rest of the line in case it was really long */
while ( input[sizeof(input)-2] && input[sizeof(input)-2] != '\n' ) {
input[sizeof(input)-2] = '\n';
if ( fgets( input, sizeof(input), stdin ) == 0 ) break;
}

关于C、Buffer 没有按预期清除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19304074/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com