作为使用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