0

从文件读取时,我有一个关于 getline 的奇怪问题。

下面是代码。

#include <fstream>
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;

struct call {
    string l;
            string k;
};

int main () {
    ifstream read;
    string fn = "in.txt";
    string temp;
    call mc;
    vector<call> vcall;

    read.open (fn.c_str ());

    while (getline (read, temp)) {

        temp.erase (temp.end () - 1);

        if (temp.substr (0,1).compare ("L") == 0) {
            temp = temp.substr (7);
            stringstream ss (temp);
            while (ss) {
                getline (ss, mc.l, ':');
                getline (ss, mc.k, ':');
                vcall.push_back (mc);
            }
        }
    }
    for (int i = 0; i < vcall.size (); i++) {
        cout << vcall [i].i << vcall [i].k << endl;
    }

}

文本文件 in.txt 包含一行。

Los:0:A:1:B:2:C:3:D:4:E:

程序的输出给了我。

0A
1B
2C
3D
4E
4E

不知道为什么会这样。它不应该在输出中包含最后一个(另一个)4。

我尝试重新创建文本文件,在另一个文件中重新编写代码并编译。在 Ubuntu (g++) 和 Windows (mingw) 中尝试过,但仍然遇到同样的问题。

更新:

我没有使用 while (getline (ss, mc.l, ':')) 的原因是因为我需要多个部分。我对上面的代码做了一些改动,结构有 2 个字符串要存储。还对我的文本文件进行了更改以反映更改。

那么我该怎么做呢?谢谢。

4

2 回答 2

1

改变这个:

 while (ss) {
     getline (ss, mc.l, ':');
     vcall.push_back (mc);
 }

对此:

while (getline(ss, mc.l, ':')) {
    vcall.push_back(mc);
}

问题是在您已经将项目添加到向量之前,您不会检查读取是否失败。因此,当最后一次读取失败时,与上次调用 getline 保持不变的项目再次被推回向量上。一旦读取失败,修改后的版本就会退出。您在主 for 循环中使用了这个习惯用法,即从文件中读取行的循环。所以我想知道你为什么不将它与字符串流一起使用。

响应更新:

while (getline(ss, mc.l, ':') && getline(ss, mc.k, ':')) {
    vcall.push_back(mc);
}

如果您发现 while 语句中的条件变得过于笨拙,您可以随时执行以下操作:

while (true) {
    getline(ss, mc.l, ':');
    getline(ss, mc.k, ':');
    if (!ss)
        break;
    vcall.push_back(mc);
}
于 2012-11-19T18:38:52.443 回答
1

内循环:

while (ss)
{
  getline (ss, mc.l, ':');
  vcall.push_back (mc);
}

应该写成:

while (getline (ss, mc.l, ':'))
{
  vcall.push_back (mc);
}

您已经为外部循环编写了这个惯用循环。

于 2012-11-19T18:39:21.487 回答