【问题标题】:Handling exception std::out_of_range c++ [closed]处理异常std :: out_of_range c ++ [关闭]
【发布时间】:2016-01-06 01:01:37
【问题描述】:

我正在尝试将航班时刻表从文件读入 Flight 类。

我在使用 Microsoft Visual Studio 2015 时遇到了问题。我在tutorialspoint c++ 在线编译器上尝试了相同的代码,一切正常。

这是文本文件的示例数据:

LAS VEGAS; 21:15; AA223; A3;
DALLAS; 21:00; BA036; A3;
LONDON; 20:30; AA220; B4;
MEXICO; 19:00; VI303; B4;
LONDON; 17:45; BA087; B4;

这是我收到的错误消息:

sf.exe 中 0x75F25B68 处的未处理异常:Microsoft C++ 异常:内存位置 0x00C5EE9C 处的 std::out_of_range。

这里是明显出现问题的流提取器

istream &operator>>(istream &is, Flight &f) {
    std::string singleLine;
    is >> singleLine;
    std::string s0, s1, s2, s3;
    size_t loc = singleLine.find(';');
    s0 = singleLine.substr(0, loc);
    singleLine.erase(0, loc + 1);
    loc = singleLine.find(';');
    s1 = singleLine.substr(1, loc - 1);
    singleLine.erase(0, loc + 1);
    loc = singleLine.find(';');
    s2 = singleLine.substr(1, loc - 1);
    singleLine.erase(0, loc + 1);
    s3 = singleLine.substr(1, 2);


    f.set_lightNo(s0);
    f.set_destination(s1);
    f.set_departure(s2);
    f.set_gateNo(s3);
    return is;
}

【问题讨论】:

  • “它不想编译我的文件”与运行时错误相矛盾:你不能在没有编译的情况下运行程序。无论如何,请使用 Visual Studio 调试器。您可以要求它在第一次机会异常时中断。
  • 作为一个堆栈溢出问题,这需要一个完整但最小的示例。投票结束。
  • FWIW, std::string::find 可以使用第二个参数调用,该参数给出开始搜索的位置。所以每次搜索都可以在分隔符之后开始,而不需要删除前面的文本..

标签: c++ istream formatted-input


【解决方案1】:

问题是您阅读以下行:

is >> singleLine;  // <== ouch ! 

singleLine 将在遇到的第一个空格处结束,而不是整行!

在您的示例数据中,第一个空格紧跟在第一个 ; 之后。所以当你执行第二个find(';') 时,将找不到返回值,即string::npos,这是loc 可以包含的最大值(非常大的数字)。然后,当您尝试访问 substr(1, loc - 1) 时,您肯定超出了范围。

如果您将行替换为以下内容,它应该可以工作:

getline (is, singleLine); // will get the full line until nweline or eof

建议:

进一步的改进是先检查读取是否成功:

istream &operator>>(istream &is, Flight &f) {
    std::string singleLine;
    if (getline (is, singleLine)) { 
        ...
    }
    return is;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    相关资源
    最近更新 更多