来自文件的 sscanf 输入缓冲区在文件读取范围内失败但仅在文件读取范围之外工作为什么?

问题描述 投票:0回答:1

所以我不明白为什么会这样,但是这段代码的第一个方法失败了,缓冲区没有初始化我猜是在文件读取范围内,所以

sscanf
有坏数据要解析并失败。一旦
sscanf
超出文件读取范围,缓冲区就会被填充并且
sscanf
工作正常。我还曾经将输入数据归档以提供使用
sscanf
的解析函数,它也有效,有人能指出我遗漏了什么吗?

#include <stdio.h>
#include <window.h>

void readFromFile() {
    char buff[100];
    int op = 0;
    int lc = 0;
    char st[25];
    FILE *cmdBUffer;
    std::string CMDFILE = "C:\\testFile.txt";
    // example test file string 50 0005 SomeString

    //-----  This works and op and lc are in fact integers 
    cmdBuffer = fopen(CMDFILE.data(), "r");
    if (cmdBuffer != NULL) {
        fgets(buff, sizeof(buff), cmdBuffer);
        fclose(cmdBuffer);
    }
    sscanf(buff, "%d %d %s", &op, &lc, st);
    printf(" %d %d %s\n", op, lc, st);
}
    //-----  this always fails ----
    cmdBuffer = fopen(CMDFILE.data(), "r");
    if (cmdBuffer != NULL) {
        fgets(buff, sizeof(buff), cmdBuffer);
        sscanf(buff, "%d %d %s", &op, &lc, st);
        fclose(cmdBuffer);
    }
    printf("%d %d %s, &op\n", &lc, st); // op and lc are always zero after sscanf fail
c++ c++11 scanf
1个回答
0
投票

有多个问题:

  • 您必须更明确和准确地处理错误:如果您无法打开文件,
    buff
    保持未初始化状态,因此传递给
    sscanf()
    是没有意义的并且具有未定义的行为。您应该报告错误并使用
    op
    lc
    st
    的默认值。
  • 您不检查
    sscanf()
    的返回值,因此有办法判断
    sscanf
    fails 以及原因。如果
    sscanf()
    返回与 3 不同的任何内容,则部分或所有目标变量未修改,并且
    st
    保持未初始化状态,导致
    printf
    调用中出现未定义的行为。
  • 您在
    %s
    中使用
    sscanf
    :这是有风险的,因为
    buff
    可能包含一个长于
    24
    字节的单词。使用
    sscanf(buff, "%d %d %24s", &op, &lc, st)
    避免缓冲区溢出。
  • printf("%d %d %s, &op\n", &lc, st)
    中传递
    lc
    的地址而不是它的值。然后你打印
    &op
    而不是传递
    op
    值......你应该使用
    printf("%d %d %s\n", op, lc, st)
© www.soinside.com 2019 - 2024. All rights reserved.