如何有效地管理缓冲区溢出而不影响C中的其他变量?



作为使用Python后的C初学者,我遇到了一个非常简单的问题,我就是无法解决。

虽然我见过很多关于1个输入缓冲区溢出的解决方案,但我似乎找不到2个输入缓冲区溢出的解决方案。

我的程序只是使用scanf()对两个最大长度为16的不同变量收集输入字符,同时也尽量不存储n。然后程序输出输入的变量。

代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Enter a word: ");
char word1[16];
scanf(" %16s", word1);
fflush(stdin);
printf("Enter another word: ");
char word2[16];
scanf(" %16s", word2);
fflush(stdin);
printf("Your first input: %sn", word1);
printf("Your second input: %sn", word2);

return 0;
}

当我输入长度限制以内的字符串时,一切正常,但是一旦第二个输入更长,一切都变得混乱,即使我的第一个输入是有效的。

.

工作的例子:

输入1 = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

输入2 = ok

word1 = aaaaaaaaaaaaaaaaa

word2 = ok

失败的例子:

输入1 = ok

输入2 = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

word1 =

word2 = aaaaaaaaaaaaaaaaa

.

我唯一的解决方案是缩短scanf()读取到15(1小于字符串的存储容量)

printf("Enter a word: ");
char word1[16];
scanf(" %15s, word1);

但是为什么16不行呢?还有其他办法可以解决吗?

我也一直听说fflush()是非常有问题的,不应该使用。为什么呢?

如果你对这个问题和我如何创建公共问题有任何其他建议,请告诉我,因为这是我第一次使用这个网站。

C语言中的字符串只是字符数组。C不知道字符串有多长,所以它以空字节结束字符串(即。0).字符串"ok ">五个字节:{'o', 'k', 'a', 'y', ''}.

char word1[16]有16个字节的空间,但是只有15个字符加上空字节。

分配17个字符,或者限制自己输入15个字符。

char word1[16];
scanf(" %15s", word1);

处理这个问题的一种常见方法是分配一个大的缓冲区,读入其中,然后将输入复制到大小合适的内存块中。

char input[1024];
printf("Enter a word: ");
scanf(" %1023s", input);
char *word1 = strdup(input);
printf("Enter another word: ");
scanf(" %1023s", input);
char *word2 = strdup(input);

我也听说fflush()非常有问题,不应该使用。为什么呢?

虽然有些实现允许将其用于输入(MacOS, Visual Studio),但这是非标准行为,并且在编译器之间不一致。标准fflush仅用于输出。最好不要依赖于特定于实现的行为,在可能的情况下坚持标准。

fflush(stdin);调用未定义行为。不要这样做。

但是为什么它不能与16一起工作?还有其他办法可以解决吗?

C语言中的字符串在末尾有一个特殊的字符,叫做空终止字符。所以如果你有一个16个字符的数组,你只能存储15个字符+ 1个空终止字符。这是正确的行为,你需要永远记住它。

int main(int argc, char *argv[])
{
char str[] = "12345";
printf("strlen(str) = %zu, sizeof(str) = %zun", strlen(str), sizeof(str));
}

https://godbolt.org/z/hz416hqer

strlen(str) = 5, sizeof(str) = 6

相关内容

  • 没有找到相关文章

最新更新