while(getline(fin,str)){}甚至在达到eof之后仍在处理数据

问题描述 投票:0回答:2

我正在尝试使用getline()作为条件处理从文件读取的数据。但是,即使getline读取到文件的末尾,它仍会继续处理数据,而且我不知道为什么。

我尝试将fin.ignore放在while循环的末尾,这确实解决了一个问题,但创建了另一个问题。让我告诉你我的意思。

这是我的代码:

   int i{ 0 };
   string name_buffer;
   string quantity_buffer;
   string price_buffer;
   ifstream fin("in_inventory.txt");
   if (fin) {
      while (getline(fin, name_buffer, ';') && i < g_kMaxArray) {
         getline(fin, quantity_buffer, ';');
         getline(fin, price_buffer, '\n');
         p_item_list_[i] =  new Product(stoi(quantity_buffer) == 0, name_buffer, stoi(quantity_buffer), stod(price_buffer));
         i++;
         item_count_++;
      }
   }
   else {
      cout << "Error: Failed to open input file." << endl;
   }
   fin.close();

我阅读了此文本文件:

AMD Ryzen 1600X 6-Core CPU;9;99.99
WD Blue 1TB HDD;24;49.99
MSI GTX 1080 Duke Graphics Card;6;519.99
NZXT H442 ATX Case;21;89.99
MSI B350 ATX Motherboard;19;149.99
WD Blue 256GB SSD;28;69.99
Cooler Master Hyper 212 Evo CPU Heatsink;41;15.99
Corsair Vengance 8Gb (2x4GB) Dual Channel Memory;18;39.99
Corsair CX650M 650 Watt Powersupply;16;59.99
Schiit Fulla 2;25;89.99
Logitech G410 Tenkeyless Mechanical Keyboard;7;79.99
Corsair H100iv2 All-in-one CPU Water Cooler;14;109.99
Steel Series Qck+ Mousepad;54;18.99
TP-Link Archer T6E PCIe WiFi Card;42;39.99
Logitech G502 Mouse;61;47.00
Beyerdynamic DT 770 Studio Headphones;36;178.99

据我所知,没有丢失或多余的分号,并且文件末尾没有换行符。

这是我没有fin.ignore()的输出:

____________________________________________________________________________________
|Item ID|Restocking?|Name                                            |Quantity|Price |
 ------------------------------------------------------------------------------------
|   5708|   false   |AMD Ryzen 1600X 6-Core CPU                      |9       |99.99 |
|   2760|   false   |WD Blue 1TB HDD                                 |24      |49.99 |
|   7220|   false   |MSI GTX 1080 Duke Graphics Card                 |6       |519.99|
|   4110|   false   |NZXT H442 ATX Case                              |21      |89.99 |
|   9026|   false   |MSI B350 ATX Motherboard                        |19      |149.99|
|   9636|   false   |WD Blue 256GB SSD                               |28      |69.99 |
|   5559|   false   |Cooler Master Hyper 212 Evo CPU Heatsink        |41      |15.99 |
|   5541|   false   |Corsair Vengance 8Gb (2x4GB) Dual Channel Memory|18      |39.99 |
|   7406|   false   |Corsair CX650M 650 Watt Powersupply             |16      |59.99 |
|   2568|   false   |Schiit Fulla 2                                  |25      |89.99 |
|   4904|   false   |Logitech G410 Tenkeyless Mechanical Keyboard    |7       |79.99 |
|   7280|   false   |Corsair H100iv2 All-in-one CPU Water Cooler     |14      |109.99|
|   4299|   false   |Steel Series Qck+ Mousepad                      |54      |18.99 |
|   8583|   false   |TP-Link Archer T6E PCIe WiFi Card               |42      |39.99 |
|   1103|   false   |Logitech G502 Mouse                             |61      |47.00 |
|   4709|   false   |Beyerdynamic DT 770 Studio Headphones           |36      |178.99|
|   2900|   false   | //This line shouldn't exist
                                               |36      |178.99| //This line shouldn't exist
 ------------------------------------------------------------------------------------

这是我用fin.ignore的输出,它删除了多余的输出,但是删除了第一个产品之后每个产品名称的第一个字符:

 ____________________________________________________________________________________
|Item ID|Restocking?|Name                                            |Quantity|Price |
 ------------------------------------------------------------------------------------
|   6293|   false   |AMD Ryzen 1600X 6-Core CPU                      |9       |99.99 |
|   3407|   false   |D Blue 1TB HDD                                  |24      |49.99 |
|   3638|   false   |SI GTX 1080 Duke Graphics Card                  |6       |519.99|
|   2358|   false   |ZXT H442 ATX Case                               |21      |89.99 |
|   3370|   false   |SI B350 ATX Motherboard                         |19      |149.99|
|   1620|   false   |D Blue 256GB SSD                                |28      |69.99 |
|   5632|   false   |ooler Master Hyper 212 Evo CPU Heatsink         |41      |15.99 |
|   5847|   false   |orsair Vengance 8Gb (2x4GB) Dual Channel Memory |18      |39.99 |
|   3866|   false   |orsair CX650M 650 Watt Powersupply              |16      |59.99 |
|   6181|   false   |chiit Fulla 2                                   |25      |89.99 |
|   1202|   false   |ogitech G410 Tenkeyless Mechanical Keyboard     |7       |79.99 |
|   5170|   false   |orsair H100iv2 All-in-one CPU Water Cooler      |14      |109.99|
|   2230|   false   |teel Series Qck+ Mousepad                       |54      |18.99 |
|   8477|   false   |P-Link Archer T6E PCIe WiFi Card                |42      |39.99 |
|   5789|   false   |ogitech G502 Mouse                              |61      |47.00 |
|   5263|   false   |eyerdynamic DT 770 Studio Headphones            |36      |178.99|
 ------------------------------------------------------------------------------------

什么是最好的解决方案?到底是什么导致了此输出?谢谢。

c++ file-io getline
2个回答
2
投票

在外部while循环中,一次读取一行str,然后在内部while循环中,从刚刚提取的行中提取每个字段,如下所示:

if (fin.is_open()) {
    string str, buffer;     
    while (getline(fin, str) && item_count_< g_kMaxArray) {
        stringstream line{ str };
        int field_count = 0;
        cout << endl << "New Line - " << str << endl;
        string field0, field1, field2;
        while (getline(line, buffer, ';')) { 
            field_count == 0 ? field0 = buffer : field_count == 1 ? field1 = buffer : field2 = buffer;
            field_count++;
        }
        p_item_list_[item_count_] = new Product(stoi(field1) == 0, field0, stoi(field1), stod(field2));
        item_count_++;
    }
}

0
投票

您的while条件错误。

while (i < g_kMaxArray && // MUST be first
     getline(fin, name_buffer, ';') &&
     getline(fin, quantity_buffer, ';') &&
     getline(fin, price_buffer, '\n')) { 
   ...
 }

在您的情况下,逐行读取输入并解析每一行可能更好。这只是在同一循环迭代中读取多个输入的通用方法。

© www.soinside.com 2019 - 2024. All rights reserved.