简体   繁体   中英

Parsing strings, ints and floats from text file

I have the following text file:

Jean Rousseau
1001 15.50
Steve Woolston
1002 1423.20
Michele Rousseau
1005 52.75
Pete McBride
1007 500.32
Florence Rousseau
1010 1323.33
Lisa Covi
1009 332.35
Don McBride
1003 12.32
Chris Carroll
1008 32.35
Yolanda Agredano
1004 356.00
Sally Sleeper
1006 32.36

I have to store the strings (Jean Rousseau), int s ( 1001 ) and float s ( 15.50 ) in 3 std::vectors .

I have a working solution, but would like to know if it's the proper way to do it.

My code is the following:

int counter=0;
std::string line;
std::ifstream myfile("InFile.txt");
std::vector<std::string> names;
std::vector<int> ids;
std::vector<float> balances;
int buf_int;
float buf_float;
while(myfile) {
   std::getline(myfile, line);
   std::cout << line << std::endl;
   std::stringstream ss(line);
   if(counter%2 == 0) {
        names.push_back(line);
   }
   else {
          if(ss >> buf_int) ids.push_back(buf_int);
          if(ss >> buf_float) balances.push_back(buf_float);
   }
   counter++;
}

Please let me know if there is a better way to do it. Thanks.

As πάντα ῥεῖ said. What is better? Your question will possibly be closed, because of asking for opinions. Anyway. I would like to give one alternative answer using algorithms.

In my opinion the 3 data 'name', 'id' and 'balance' belong together. Therefore, I would put them in a struct. (And yes, I ignore your wish to have 3 separate vectors. I apologize.)

And because we want to read this data, we will overload the extractor operator. And the inserter operator as well. Maybe later some additional functionality can be added. That will then be more easy.

And because there should be many of these data, a std::vector is the ideal solution to store that.

Having the 3 items in a struct, we can easily read all items together and put them afterwards in the vector.

And for reading the whole file in function main, we use a one liner. We define the vector variable with the range constructor.

And then we copy the complete vector with all data to std::cout.

Please note. I did no error handling. This needs to be added. But this is a simple task to do. At the moment, the program stops reading, as soon as some not matching text is found. Eg: Last line must have a "\\n".

Please see:

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <iterator>

// Name Id and balance belong together. Therefore, we put it together in one struct
struct NameIdBalance    
{
    std::string name{}; int id{0};  float balance{0.0};
    // And since we want to read this data, we overload the extractor
    friend std::istream& operator>>(std::istream& is, NameIdBalance& nid) { 
        std::getline(is, nid.name); 
        is >> nid.id >> nid.balance;   is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        return is;  
    }
    // For debug purposes, we also overload the inserter
    friend std::ostream& operator << (std::ostream& os, const NameIdBalance& nid) { return os << "Name: " << nid.name << " (" << nid.id << ") --> " << nid.balance; }
};

int main()
{
    // 1. Open File
    std::ifstream myfile("r:\\InFile.txt");
    // 2 Read all data into a vector of NameIdBalance
    std::vector<NameIdBalance> nameIdBalance{ std::istream_iterator<NameIdBalance>(myfile), std::istream_iterator<NameIdBalance>() };

    // For debug purposes: Print complete vector to std::cout
    std::copy(nameIdBalance.begin(), nameIdBalance.end(), std::ostream_iterator<NameIdBalance>(std::cout, "\n"));
    return 0;
}

But there are 42 million other possible solutions . . . _ :-)

EDIT:

After LightnessRacesinOrbit hint, I removed the word POD. the struct is not a POD.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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