Why does reading a record struct fields from std::istream fail, and how can I fix it?

后端 未结 9 2302
野性不改
野性不改 2020-11-21 11:40

Suppose we have the following situation:

  • A record struct is declared as follows

struct Person {
    unsigned int id;
    std::st         


        
9条回答
  •  春和景丽
    2020-11-21 12:22

    Another attempt at solving the parsing problem.

    int main()
    {
       std::ifstream ifs("test-115.in");
       std::vector persons;
    
       while (true)
       {
          Person actRecord;
          // Read the ID and the first part of the name.
          if ( !(ifs >> actRecord.id >> actRecord.name ) )
          {
             break;
          }
    
          // Read the rest of the line.
          std::string line;
          std::getline(ifs,line);
    
          // Pickup the rest of the name from the rest of the line.
          // The last token in the rest of the line is the age.
          // All other tokens are part of the name.
          // The tokens can be separated by ' ' or '\t'.
          size_t pos = 0;
          size_t iter1 = 0;
          size_t iter2 = 0;
          while ( (iter1 = line.find(' ', pos)) != std::string::npos ||
                  (iter2 = line.find('\t', pos)) != std::string::npos )
          {
             size_t iter = (iter1 != std::string::npos) ? iter1 : iter2;
             actRecord.name += line.substr(pos, (iter - pos + 1));
             pos = iter + 1;
    
             // Skip multiple whitespace characters.
             while ( isspace(line[pos]) )
             {
                ++pos;
             }
          }
    
          // Trim the last whitespace from the name.
          actRecord.name.erase(actRecord.name.size()-1);
    
          // Extract the age.
          // std::stoi returns an integer. We are assuming that
          // it will be small enough to fit into an uint8_t.
          actRecord.age = std::stoi(line.substr(pos).c_str());
    
          // Debugging aid.. Make sure we have extracted the data correctly.
          std::cout << "ID: " << actRecord.id
             << ", name: " << actRecord.name
             << ", age: " << (int)actRecord.age << std::endl;
          persons.push_back(actRecord);
       }
    
       // If came here before the EOF was reached, there was an
       // error in the input file.
       if ( !(ifs.eof()) ) {
           std::cerr << "Input format error!" << std::endl;
       } 
    }
    

提交回复
热议问题