Reputation: 314
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
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
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