Kabocha Porter
Kabocha Porter

Reputation: 301

simplify reading from file with comma using extraction operator?

I want to read from a file that consists of entries in each line that look like this:

BA,1355,SIN,3316,MEL,3339,Y,0,744
BA,1355,SIN,3316,LHR,507,,0,744 777

I want to store the first 6 columns and save them to string and int respectively.

At the moment, I have use getline to handle the comma, as shown below. But the drawbacks are 1) getline can only store things in string, so the numbers are saved as string instead of int 2) the code is repetitive

Is there a way that I can use the and string::ignore and >> operator in stringstream to accomplish the same thing? something like linestream>> airline >> airlineNo >> scr >> scrNum >> det >>detNum; where airlineNo, scrNumand detNum are numbers?

while (getline(myfile, temp)) {
        //std::cout<<temp<<std::endl;
        std::stringstream linestream(temp);
        std::string line;

        std::string airline, scr, det; 
        std::string airlineNo, scrNum, detNum;

        getline(linestream, airline, ',');
        getline(linestream, airlineNo, ',');
        getline(linestream, scr, ',');
        getline(linestream, scrNum, ',');
        getline(linestream, det, ',');
        getline(linestream, detNum, ',');
        
        std::cout<<scr<<" "<<det<<std::endl;
        
    }

Upvotes: 0

Views: 88

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 596938

You can certainly use operator>> with a std::(i)stringstream, eg:

while (getline(myfile, temp)) {
    //std::cout << temp << std::endl;
    std::istringstream linestream(temp);

    std::string airline, scr, det; 
    int airlineNo, scrNum, detNum;

    getline(linestream, airline, ',');
    linestream >> airlineNo;
    linestream.ignore(std::numeric_limits<std::streamsize>::max(), ',');
    getline(linestream, scr, ',');
    linestream >> scrNum;
    linestream.ignore(std::numeric_limits<std::streamsize>::max(), ',');
    getline(linestream, det, ',');
    linestream >> detNum;
        
    std::cout << scr << " " << det << std::endl;      
}

Alternatively, just use std::stoi() on the strings that std::getline() outputs, eg:

while (getline(myfile, temp)) {
    //std::cout << temp << std::endl;
    std::istringstream linestream(temp);

    std::string airline, scr, det; 
    int airlineNo, scrNum, detNum;

    getline(linestream, airline, ',');
    getline(linestream, temp, ‘,’);
    airlineNo = std::stoi(temp);
    getline(linestream, scr, ',');
    getline(linestream, temp, ‘,’);
    scrNum = std::stoi(temp);
    getline(linestream, det, ',');
    getline(linestream, temp, ‘,’);
    detNum = std::stoi(temp);
        
    std::cout << scr << " " << det << std::endl;      
}

Upvotes: 1

Sean
Sean

Reputation: 16

If you're sure the first six fields are going to be filled, what you could do is replace every comma in a line to spaces, so that you can then use operator<< to get objects nicely. This doesn't work if any of the important fields are empty.

for (int i = 0; i < temp.size(); ++i) {
    if (temp[i] == ',') temp[i] = ' ';
}
std::stringstream linestream(temp);
/*...*/
linestream >> airline >> airlineNo >> scr >> scrNum >> det >> detNum;    

Upvotes: 0

Related Questions