为什么我的fscanf()没有读取中间变量?

时间:2014-08-19 16:59:01

标签: c scanf

这可能是一个非常简单的修复,但我没有看到它。 假设我的文件看起来像这样:

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,而不是像我上面所声称的那样无符号。当我改变它时,代码完美无缺。

任何想法为什么会导致它忽略第二个字符串但仍然拿起整数?

1 个答案:

答案 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个字节为它保留,溢出不会发生。