这可能是一个非常简单的修复,但我没有看到它。 假设我的文件看起来像这样:
Katze cat 1
Hund dog 1
Fisch fish 3
我用这个来读它:
char a[1000], b[1000];
unsigned box;
while(fscanf(in, "%s %s %u", a, b, &box) == 3) {
然后,为了检查,我之后立即将其放入:
printf("\njust read: '%s' '%s' '%u'", a, b, box);
我得到的输出是:
just read: 'Katze' '' '1'
just read: 'Hund' '' '1'
just read: 'Fisch' '' '3'
我无法弄清楚第二根弦的去向。
满足更多代码的请求:
if(argc==3 && (!strcmp(argv[1], "test"))){
//try to open the 3rd argument, to read.
if((in = fopen(argv[2], "r")) == NULL){
printf("\n%s: cannot open '%s'\n", argv[0], argv[2]);
exit(1);
}
//read data from .fee file.
while(fscanf(in, "%s %s %u", a, b, &box) == 3) {
printf("\njust read: '%s' '%s' '%u'", a, b, box);
更新: 我修复了它,但我仍然不明白为什么错误表现了它的方式。问题在于,事实上,我已经将'box'定义为char,而不是像我上面所声称的那样无符号。当我改变它时,代码完美无缺。
任何想法为什么会导致它忽略第二个字符串但仍然拿起整数?
答案 0 :(得分:3)
如果将“box”定义为char(1个字节),则fscanf仍将向该地址写入4个字节(因为fscanf格式中有%u)。数据类型与fscanf格式类型不匹配会导致缓冲区溢出。
当fscanf运行时,它会将数据写入“a”缓冲区,然后将数据写入“b”缓冲区,然后将数据写入内存中的“box”。由于“box”为它保留了1个字节(char),但fscanf写入4个字节(unsigned int),因此存在溢出。
在第一行的情况下,fscanf会将字节0x01,0x00,0x00,0x00写入“box”。如果“b”缓冲区刚好在堆栈的“box”之后,则3个零将覆盖“b”中的前3个字节,“b”将覆盖空字符串而不是您在那里的数据。
一旦你将“box”改为unsigned int,它现在有4个字节为它保留,溢出不会发生。