繁体   English   中英

C ++:从txt文件逐行和逐单词读取,每行单词数量不均匀

[英]C++: Reading from a txt file line by line and word by word with uneven amount of words each line

晚上好,

我有一个txt文件,其中包含有关某些汽车的信息。 根据类型,每辆车都有自己的属性,例如:

1型汽车具有名称,购买价格,租赁价格。

2型车有名称和购买价格。

3型车有名称和购买价格。

4型车具有名称,购买价格,租赁价格和保险价格。

Type(Int)  Name(String)         Buy(Int)     Rent(Int)   Insurance(Int) 
1          toyota               5000         100   
3          mazda                6000         130
2          mitsubishi           10000   
1          honda                5000         110
4          ferrari              20000        220         1000

现在,我要做的就是读取文件并打印每辆车的类型,以便我知道我的代码有效。 到目前为止,我尝试过的是:

ifstream carsFile(cars.txt);

string carType;
string carName;
string carBuyPrice;
string carRentPrice;
string carInsPrice;
string line;

while (getline(carsFile, line))
{
    istringstream buffer(line);

    while (buffer >> carType >> carName >> carBuyPrice >> carRentPrice >> carInsPrice)
    {
         if (carType == "1")
         {
            cout << "Car type 1" << endl;
         }
         else if (carType == "2")
         {
            cout << "Car type 2" << endl;
         }
         else if (carType == "3")
         {
            cout << "Car type 3" << endl;
         }
         else
         {
         cout << "Car type 4" << endl;
         }
    }
}

carsFile.close();

上面的代码仅适用于类型2和3(它们具有相同的属性),即使行中的单词数不均匀,如何读取每种类型?

任何帮助表示赞赏。

我强烈建议为文件中的记录建模结构。 接下来,使用重载operator>>读取字段。
例:

struct Car_Info
{
  int type;
  std::string manufacturer;
  int buy_price;
  int rent_price;
  int insurance_price;
// Here's the kicker
  friend std::istream&  operator>>(std::istream& input, Car_Info& ci);
};

std::istream&  operator>>(std::istream& input, Car_Info& ci)
{
  std::string text_line;
  std::getline(input, text_line);
  if (input)
  {
    std::istringstream text_stream(text_line);
    // Initialize optional fields
    ci.rent_price = 0;
    ci.insurance_price = 0;
    text_stream >> ci.type
        >> ci.manufacturer
        >> ci.buy_price;
        >> ci.rent_price
        >> ci.insurance_price;
    }
}

您的输入循环如下所示:

std::vector<Car_Info> database;
Car_Info car;
while (input_file >> car)
{
   database.push_back(car);
}

使用该结构代替并行阵列可以减少由同步错误引起的缺陷。

字符串用于读取一条文本记录。 任何读取问题(例如eof)都会更改输入流的状态,因此使用字符串流来隔离由丢失字段所产生的错误。

内部while循环的条件是执行所有格式化的输入操作后流的状态(转换为布尔表达式)。 如果其中任何一个失败,流将被标记为错误,导致条件评估为false

您需要单独检查输入操作。

用于演示目的的实时示例

while(std::getline(std::cin, line)) {
  std::cout
    << "have \"" << line << "\"\n"
    << "read together:\n";
  read_together(line);
  std::cout << "read separately:\n";
  read_separately(line);
}

void read_separately(std::string const & line) {
  std::istringstream buffer(line);
  int a;
  int b;
  if (! (buffer >> a)) std::cout << "- a failed" << std::endl;
  if (! (buffer >> b)) std::cout << "- b failed" << std::endl;
}

void read_together(std::string const & line) {
  std::istringstream buffer(line);
  int a;
  int b;
  if (! (buffer >> a >> b)) std::cout << "- a or b failed" << std::endl;
}

当您buffer >> carType >> carName >> carBuyPrice >> carRentPrice >> carInsPrice ,您试图读取所有这些信息而不检查它们是否存在,从而导致输入失败并且循环主体不成立被执行。 为什么首先需要while循环?

您应该首先输入汽车的类型,然后输入诸如if语句或switch语句之类的内容来决定每种汽车的处理方式。

while(getline(carsFile, line))
{
    istringstream buffer(line);
    int type, rent, insurance;
    string name;
    buffer >> type >> name;
    switch(type)
    {
    case 1:
        buffer >> rent;
        //...
    case 2:
        //...
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM