fscanf不会读取每行中的第一个变量

时间:2014-05-26 19:57:39

标签: c++ file scanf

我正在尝试从文件中读取信息,但我的代码不会读取每行中的第一个输入。

这是我的代码:

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;

int main()
{
FILE* inFile;
long long int time;
char state, ID[12], name[51];

inFile = fopen("file.i2", "r");

while (fscanf(inFile, "%i %s %s %[^\n]s",&time ,&state, &ID, &name)!=EOF)
        cout << time << ' ' << state << ' ' << ID << ' ' << name << endl;

return 0;
}

这是输入:

1111 A 01010112345 SomeString1
1112 A 01010154321 SomeString2
1113 A 11111122222 SomeString3
1114 B 12121233333 SomeString4
1115 B 12121233333 SomeString5

这是输出:

1024 A 01010112345 SomeString1
1024 A 01010154321 SomeString2
1024 A 11111122222 SomeString3
1024 B 12121233333 SomeString4
1024 B 12121233333 SomeString5

在我的情况下,输出应该与输入相同。

2 个答案:

答案 0 :(得分:0)

您有未定义的行为,因为当使用%s格式时您的状态变小(null终止字符串)。您还希望使用%Ld格式读入长整数。

long long int time;
char state[2], ID[12], name[51];
           ^ 
//         make room for '\0'


while ( fscanf( inFile, "%Ld %1s %11s %50[^\n]s",&time ,&state, &ID, &name) != 4)
        cout << time << ' ' << state << ' ' << ID << ' ' << name << endl;

但是你应该使用std::ifstream。这样,变量转换的问题就会减少。请注意,我们现在指定scanf读取的字符数(%2s,%12s,%51s),现在我们测试== 4的fscanf是成功读取元素的数量,因为scanf返回的值是< / p>

  

成功分配的接收参数数,如果已读取则为EOF   在分配第一个接收参数之前发生故障。

http://en.cppreference.com/w/c/io/fscanf

答案 1 :(得分:0)

您在fscanf()的尝试以多种方式被破坏:

  1. 要阅读long long int,您需要使用长度修饰符ll。您传递了long long int的地址,其中int是预期的。现在一切都是未定义的行为。
  2. 要阅读字符,格式说明符为%c而非%s
  3. 虽然没有严格错误,但字符串不会将大小限制为可用长度:为避免因缓冲区溢出而导致漏洞,您应指定最大大小。
  4. fscanf()返回成功转化的次数。只有在没有任何转化成功的情况下才会返回结果EOF,即您应该针对4而不是EOF进行测试。
  5. 使用转化

    while (fscanf(inFile, "%lli %c %s %[^\n]s",&time ,&state, &ID, &name) == 4) {
        cout << time << ' ' << state << ' ' << ID << ' ' << name << '\n';
    }
    

    应该可以正常工作。我建议使用流作为输入,因为它们会自动进行转换:

    std::ifstream in("file.i2");
    while ((in >> time >> state >> std::setw(12) >> ID).getline(name, 51)) {
        cout << time << ' ' << state << ' ' << ID << ' ' << name << '\n';
    }
    

    尽管在阅读字符串时仍需要设置大小,但这样的错误要少得多。