C ++:逐行读取txt文件,逐行读取每行不均匀的单词

时间:2018-04-01 17:40:09

标签: c++

晚上好,

我有一个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(具有相同的属性),即使行的单词数量不均,我如何读取每个类型?

感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

我强烈建议将结构建模到文件中的记录。接下来,重载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)都将改变输入流的状态,因此字符串流用于隔离由缺失字段生成的错误。

答案 1 :(得分:1)

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

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

Live example用于演示目的:

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;
}

VS

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;
}

答案 2 :(得分:0)

执行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:
        //...
    }
}