getline项返回空变量

时间:2014-12-07 02:30:11

标签: c++ parsing text getline

我正在尝试阅读文本文件并将这些行分隔为城市和位置。一切都适用于大多数线路,但是因为我得到了一个

terminate called after throwing and instance of 'std::invalid_argument'
   what(): stoi
Aborted (core dumped)

经过一番调查后,我发现它挂在了秘鲁利马的2号。我可能是getline函数给它无法处理的东西,但是在文档前面的完全相同的位置存在完全相同的数字的实例。

...
Hobart, Tasmania: 42 52 S 147 19 E
Hong Kong, China: 22 20 N 114 11 E
Iquique, Chile: 20 10 S 70 7 W
Irkutsk, Russia: 52 30 N 104 20 E
Jakarta, Indonesia: 6 16 S 106 48 E
Johannesburg, South Africa: 26 12 S 28 4 E
Kingston, Jamaica: 17 59 N 76 49 W
Kinshasa, Congo: 4 18 S 15 17 E
Kuala Lumpur, Malaysia: 3 8 N 101 42 E
La Paz, Bolivia: 16 27 S 68 22 W
Leeds, England: 53 45 N 1 30 W
Lima, Peru: 12 0 S 77 2 W
Lisbon, Portugal: 38 44 N 9 9 W
Liverpool, England: 53 25 N 3 0 W
London, England: 51 32 N 0 5 W
Lyons, France: 45 45 N 4 50 E
Madrid, Spain: 40 26 N 3 42 W
...

以下是我认为抛出错误的代码部分。如果需要,我可以发布更多,但我认为这是相关部分。

while(is_more_stuff_there(file_to_read))
{
    getline(file_to_read, line);

    // parse city
    index = line.find(':');
    city_name = line.substr(0 , line.find(':'));
    istringstream position_stream(line.substr(index + 2 , line.find(':')));

    cout << city_name << endl;

    // initialize an array to store the parsed values from the position_string
    string position_array[6];
    string item;
    int i = 0;

    // fill the array, split by spaces
    while (getline(position_stream, item, ' '))
    {
        position_array[i] = item;
        i++;
        cout << item << endl;
    }

    cout << position_array[4] << endl;

    // initialize the position variables
    lat_min = stoi(position_array[0]);
    lat_sec = stoi(position_array[1]);
    long_min = stoi(position_array[3]);
    long_sec = stoi(position_array[4]);

    // determine positivity of lats and longs
    if (position_array[2] == "S") { lat_min *= -1; lat_sec *= -1; }
    if (position_array[5] == "E") { long_min *= -1; long_sec *= -1; }   

    vertex city(city_name, lat_min, lat_sec, long_min, long_sec);
    g.add_vertex(city);
}

2 个答案:

答案 0 :(得分:2)

文本文件中有一个非打印字符,就在有问题的2之前。你可以通过使用od -x找到它究竟是什么(如果你在unix盒子里)。或者只需删除该行并重新键入即可。

答案 1 :(得分:1)

我可以在您的代码中看到的一个问题是传递给substr函数的第二个参数似乎是错误的。它应该是要提取的子字符串的长度,但不需要与:的索引重合。您可以简单地保留第二个参数以获取整个剩余的子字符串。

std::istringstream position_stream(line.substr(index + 2));

如果只向index添加1,则代码也将解析冒号后没有空格的输入。

虽然没有根本错误,但可以通过使用C ++样式提取运算符来简化代码。您可以直接从流中读取您的四个字段。

int lat_min, lat_sec, long_min, long_sec;
std::string ns, we;
position_stream >> lat_min >> lat_sec >> ns >> long_min >> long_sec >> we;

然后继续使用所需的逻辑处理它们。