【问题标题】:Duplicate Data when I retrieve the data from file in C++当我从 C++ 文件中检索数据时重复数据
【发布时间】:2013-09-26 04:47:36
【问题描述】:

首先,我的文件中有一个数据...

1|Malaysia|UK|One-Way|20|6|20|6|2000|12|12|12|12|12|

以上数据是我文件里面的数据

但是当我计算数据时,有一个重复的数据......

1|Malaysia|UK|One-Way|20|6|20|6|2000|12|12|12|12|12|
1|Malaysia|UK|One-Way|20|6|20|6|2000|12|12|12|12|12|

那么当我 cout 数据时有什么问题??? 这是代码......

void Flight::displayFlight(vector <Flight> &flightProfile)
{
string readFlightID, readPrice, readBusinessList, readBusinessWaitingList, readEconomicList,            readEconomicWaitingList;
flightProfile.erase(flightProfile.begin(),flightProfile.end());
ifstream inFlight("Flight.txt");
if(inFlight.fail()) return;
while(!(inFlight.eof()))
{
    getline(inFlight,readFlightID,'|');
    istringstream(readFlightID)>>flightID;
    getline(inFlight,departure,'|');
    getline(inFlight,destination,'|');
    getline(inFlight,flightType,'|');
    getline(inFlight,readBusinessList,'|');
    istringstream(readBusinessList)>>businessList;
    getline(inFlight,readBusinessWaitingList,'|');
    istringstream(readBusinessWaitingList)>>businessWaitingList;
    getline(inFlight,readEconomicList,'|');
    istringstream(readEconomicList)>>economicList;
    getline(inFlight,readEconomicWaitingList,'|');
    istringstream(readEconomicWaitingList)>>economicWaitingList;
    getline(inFlight,readPrice,'|');
    istringstream(readPrice)>>price;
    getline(inFlight, day,'|');
    getline(inFlight, month,'|');
    getline(inFlight, year,'|');
    getline(inFlight, hour,'|');
    getline(inFlight, min,'|');
    inFlight.ignore(numeric_limits<streamsize>::max(), '\n');
    cout<<flightID<<departure<<destination<<flightType<<businessList<<businessWaitingList<<economicList<<economicWaitingList<<price<<day<<month<<year<<hour<<min<<endl;
}
inFlight.close();
}

【问题讨论】:

  • 当我看到问题中的“重复”一词时,我知道这将是eof()-abuse,然后才打开它。
  • @KerrekSB LOL...这是什么意思?
  • eof() 并不代表您的想法,也不会按照您的想法工作。你会在这个网站上找到数以千计的类似问题,或者你可以自己阅读手册......
  • @KerrekSB 公平地说,您还会发现 1000 多个教程、示例代码等告诉您这是从文件中读取的正确方法。这个想法似乎很持久,尽管它很容易被证明是错误的,但我认为这必须作为一个糟糕的 API 设计。人们就是不明白。

标签: c++ file vector fstream getline


【解决方案1】:

如果流处于良好状态,您总是需要检查您从流中读取后!如果读取数据失败,例如,因为到达流的末尾,流将处于失败状态。例如

while (std::getline(inFlight, readFlightID)
       && std::istringstream(readFlightId) >> flightID
       && std::getline(inFlight, departure)
       ...
       ) {
    // now process the read data
}

顺便说一句,请注意,使用临时流的技巧只有在目标类型是 std::istream 的成员时才有效。如果不是,则需要从流中额外引用,例如使用

std::istringstream("some text") >> std::skipws >> value

【讨论】:

  • 您真的认为将所有这些都放在while 的条件下是个好主意吗?鉴于他的格式,我会在线路上使用boost::split,但无论如何,我都会分开读取线路,以便从错误中恢复并保持同步。 (由于某种原因,如果其中一行少了一个字段,请考虑一下混乱。)
  • @JamesKanze:嗯,我认为将整数读入std::string 然后在std::istringstream 中解码std::string 并不是一个好主意。但是,我只是遵循原始代码的格式。重要的部分是检查所有输入尝试以查看它们是否成功。 ...而且,是的,我通常在一种情况下这样做,尽管它通常相当简单,因为我会为不同的结构创建输入运算符。
  • 定义应用程序特定类型并让它们重载&gt;&gt; 当然是首选的解决方案。但是对于面向行的输入,您肯定希望逐行读取(并跟踪行号),以便在错误消息中显示行号,并重新同步,而不是在第一个错误时停止处理.这可以不使用getlineistringstream 来完成,但是对于没有经验的程序员来说,getline/istringstream 的解决方案无疑是最简单的。
【解决方案2】:

您(和其他人)的常见错误是 eof 位仅在输入操作 (RTFM) 上设置。

逐行读取文件的正确方法是:

if (myfile.is_open())
  {
    while ( getline (myfile,line) )
    {
      cout << line << endl;
    }
    myfile.close();
}

【讨论】:

    【解决方案3】:

    那是因为您没有检查您的 getline 是否成功。 最后一次通过循环,它可能会失败(因为 您已经阅读了所有数据),因此您选择了旧值。

    不是读取基于行的输入的方式。对于初学者, 基于行的输入应逐行读取:

    std::string line;
    while ( std::getline( inFlight, line ) ) {
        //  Parse line here...
    }
    

    解析行的方法有很多种。最常见的一种 解决方案是将其放入std::istringstream 并阅读 从此。这对你正在做的事情来说可能是矫枉过正, 然而;您可能需要boost::split 之类的东西(其中 如果你不能使用Boost,你可以在不到一个小时内敲门)。

    无论如何,while ( !someIStream.eof() ) 永远不会正确。

    另外两个快速的 cmets:你不应该定义你的变量 在你需要它们之前,关闭没有真正意义 inFlight 如果它立即超出范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 1970-01-01
      • 2021-10-09
      • 2019-08-01
      • 1970-01-01
      • 2015-02-08
      • 2019-05-24
      相关资源
      最近更新 更多