Gavin Youker
Gavin Youker

Reputation: 314

How read from text file until comma using ifstream in C++?

I have the following database:

101884622 Johnson,Jack,Michael   239483
441314978 Meyers,Sally,Elaine    019383
684736222 Smallwood,Jason,Joseph 293812
387240551 Ward,Richard,Charles   472041
273639944 Vapson,Michelle,Regina 112039
654230472 Wilson,Donald,Anthony  528763
736459533 Utzig,Jacob,William    614524
687130851 Brown,Betty,Mary       079813

I am trying to use ifstream to make C++ output the member's first middle and last name according to the text file. How can one acomplish this? Here is my code

int main() {
    double socialSN = 0;
    string memberFName = "";
    string memberMName = "";
    string memberLName = "";
    double memberID = 0;
    char div = ',';

    ifstream infile;
    infile.open ("salary_database2.txt");
    if(!infile) {cout << "Error: File not found or corrupt. "<< endl; return 1;}

    while(infile >> socialSN >> memberLName >> div >> memberMName >> div >> memberFName >> memberID) {
        cout << setprecision(0) << fixed;
        cout << memberFName << "     " << memberMName << "     " << memberLName << endl;
    }
    return 0;
}

The compiler shows no errors. The program just doesn't show anything.

Upvotes: 0

Views: 3685

Answers (2)

LookAheadAtYourTypes
LookAheadAtYourTypes

Reputation: 1699

According to this answer:

https://stackoverflow.com/a/10376445/210971

An istream treats "white space" as delimiters. It uses a locale to tell it what characters are white space. A locale, in turn, includes a ctype facet that classifies character types. Such a facet could look something like this:

#include <locale>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <sstream>

class my_ctype : public
std::ctype<char>
{
    mask my_table[table_size];
public:
    my_ctype(size_t refs = 0)  
        : std::ctype<char>(&my_table[0], false, refs)
    {
        std::copy_n(classic_table(), table_size, my_table);
        my_table[','] = (mask)space;
    }
};

Now your program will look like this:

int main() {
    double socialSN = 0;
    string memberFName = "";
    string memberMName = "";
    string memberLName = "";
    double memberID = 0;

    ifstream infile;
    infile.open ("salary_database2.txt");
    if(!infile) {
        cout << "Error: File not found or corrupt. "<< endl; return 1;
    }
    std::locale x(std::locale::classic(), new my_ctype);
    infile.imbue(x);

    while(infile >> socialSN >> memberLName >> memberMName >>  memberFName >> memberID) {
        cout << setprecision(0) << fixed;
        cout << memberFName << "     " << memberMName << "     " << memberLName << endl;
    }
    return 0; 
}

But using getline looks cleaner and less confusing.

Upvotes: 2

Biruk Abebe
Biruk Abebe

Reputation: 2233

The extraction operator>> uses spaces as a deliminator for reading so it reads the whole first,middle and last name into memberLName with your current implementation. What you need to do is use std::getline to split the reading of the names using comma, probably something like:

while(infile >> socialSN && getline(infile, memberLName,',') &&
      getline(infile, memberMName,',') && 
      infile >> memberFName && infile >> memberID) 
{
        cout << setprecision(0) << fixed;
        cout << memberFName << "     " << memberMName << "     " << memberLName << endl;
}

Upvotes: 2

Related Questions