gpt4 book ai didi

c - %(limit)[^\n] 在 scanf 中的行为是什么?溢出安全吗?

转载 作者:行者123 更新时间:2023-12-01 12:38:55 29 4
gpt4 key购买 nike

scanf 函数的格式 %(limit)[^\n] 不安全? (其中(limit)是字符串的长度-1)

如果不安全,为什么?

是否有一种安全的方法来实现仅使用 scanf() 捕获字符串的函数?

在 Linux 程序员手册中,(在终端上键入 man scanf),s 格式表示:

Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null byte ('\0'),which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.

输入字符串总是在最大字段宽度处停止?或者只是在 GCC 上?

谢谢。

最佳答案

%(limit)[^\n]对于 scanf"通常是安全的。

在下面的示例中,最多 99 char将被读取并保存到 buf .如果有char被保存,一个'\0'将附加和cnt将是 1。

char buf[100];
int cnt = scanf("%99[^\n]", buf);

功能当然安全,但其他功能呢?


当输入是单独的时会出现问题 "\n" .

在这种情况下,buf 中没有保存任何内容并返回 0。如果下一行代码如下,则输出为 Undefined Behavior作为buf未初始化为任何内容。

puts(buf);

更好的下一行是

if (cnt == 1) puts(buf);
else printf("Return count = %d\n", cnt);

问题是因为 '\n'没有被消耗掉。

'\n'仍在等待阅读和另一个调用 scanf("%99[^\n]", buf);不会读 '\n' .


问:仅使用 scanf() 即可安全地实现捕获字符串的函数
A:迂腐地:不容易。

scanf() , fgets()等最适合阅读文本,而不是字符串。在 C 中,字符串是 char 的数组以 '\0' 结尾.通过 scanf() 输入, fgets()等通常有阅读问题 '\0'通常是 char无论如何都不在输入中。通常输入被认为是一组 char终止于 '\n'或其他空白。

如果代码正在读取以 '\n' 终止的输入, 使用 fgets()运行良好且便于携带。 fgets()它也有以各种方式处理的弱点。 getline()是一个不错的选择。

近似值是 scanf(" %99[^\n]", buf) (注意添加的 " " ),但仅此并不能解决处理过多的长行、读取多个空行、嵌入 '\0' 的问题检测、报告长度读取的能力丧失(strlen() 由于嵌入 '\0' 而不起作用)并留下尾随 '\n ' 在 stdin .

缺少使用scanf("%c", &ch)有很多周围的代码(这很愚蠢,只需使用 fgetc() ),我看不出使用单个 scanf() 的方法读取一行用户输入时绝对安全。


问:输入字符串总是停在最大字段宽度处?
答:用scanf("%99[^\n]" , 输入停止 1) 当 '\n'遇到-'\n'未保存并保留在文件输入缓冲区中 2) 99 char已读取 3) 发生 EOF 或 4) 发生 IO 错误(很少见)。

关于c - %(limit)[^\n] 在 scanf 中的行为是什么?溢出安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26887125/

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