Tellg回归意外的价值

时间:2014-10-16 08:00:04

标签: c++ file fstream ifstream file-handling

我有一个从文件中读取行的函数。但在阅读之前,它会返回从下一行读取的地址。

我的职责是:

void print()
    {
        int j=0;
        string a,b,c,d,e;
        ifstream i("data.txt");
        cout<<setw(15)<<left<<"Hash Value"<<setw(15)<<left<<"Employee Name"<<setw(15)<<left<<"Employee ID"<<setw(15)<<left<<"Salary"<<setw(15)<<left<<"Link"<<endl;
        while(j<10)
        {
            j++;
            cout<<i.tellg()<<endl;
            i>>a>>b>>c>>d>>e;
            cout<<setw(15)<<left<<a<<setw(15)<<left<<b<<setw(15)<<left<<c<<setw(15)<<left<<d<<setw(15)<<left<<e<<endl;
        }
        i.close();
    }

它正在读取的文件是data.txt:

      0            ---              0              0             -1
      1            ---              0              0             -1
      2            ---              0              0             -1
      3            ---              0              0             -1
      4            ---              0              0             -1
      5            ---              0              0             -1
      6            ---              0              0             -1
      7            ---              0              0             -1
      8            ---              0              0             -1
      9            ---              0              0             -1

我得到的输出是:

Hash Value     Employee Name  Employee ID    Salary         Link           
0
0              ---            0              0              -1             
81
1              ---            0              0              -1             
157
2              ---            0              0              -1             
233
3              ---            0              0              -1             
309
4              ---            0              0              -1             
385
5              ---            0              0              -1             
461
6              ---            0              0              -1             
541
7              ---            0              0              -1             
617
8              ---            0              0              -1             
693
9              ---            0              0              -1             

每行长度为76个字符。因此,每次打印的地址应增加76。 但我不明白当第二行打印[哈希值1]时会发生什么,并打印第7行[哈希值6]。

有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:3)

有几件事:

  • 首先,你不是逐行阅读,所以那里 没有理由认为你提前了字符数 每次通过循环一行。如果你想读行 按行,使用std::getline,然后从中提取字段 该行,使用std::istringstream或其他 方法

  • tellg的结果不是整数,而是转换为 一个整体类型(不一定可能),没有 保证与您拥有的字节数的关系 提取。在Unix机器上,结果将对应,和 在Windows下 if (仅当)文件已被打开 二进制模式。在其他系统上,可能没有可见的 关系什么如此。唯一有效的便携式使用 tellg的结果是稍后将其传递给seekg;什么 否则取决于实施。

  • 您怎么知道每行包含76个字符? 根据文件的生成方式,可能会有BOM 开始(如果文件在,则计为三个字符) 以UTF8编码,您处于“C”语言环境中)。那怎么样? 尾随空格。同样,如果您的输入是面向行的,那么您 应该读取行,然后解析它们。

  • 最后,但也许最重要的是:你正在使用 >>的结果,但未验证操作员是否正常工作。在 你的情况,输出表明它确实如此,但你永远不可能 确定无需验证。

在全球范围内,您的循环应如下所示:

std::string line;
while ( std::getline( i, line ) ) {
    std::istringstream l( line );
    std::string a;
    std::string b;
    std::string c;
    std::string d;
    std::string e;
    l >> a >> b >> c >> d >> e >> std::ws;
    if ( !l || l.get() != EOF ) {
        //  Format error in line...
    } else {
        //  ...
    }
}

输出tellg仍然不会告诉你任何事情,但至少 你会正确阅读输入。 (输出长度 line在某些情况下可能会有用。)