Reading data line by line from a text file - c++

Each line of the text file has first name, last name, and a salary. Something along the lines of this:
john doe 4000
bob miller 9000
I want my program to take the first name, last name, and salary of each line and assign them to strings (or integers). I have tried this so far:
while (inFile){
inFile >> firstName;
inFile >> lastName;
inFile >> grossPay;
cout << firstName << " " << lastName << " " << grossPay << endl;
}
When it outputs the names and the salary, the last line of the text file gets output twice by the program. How can I fix this?

After reading your last line, inFile is still in a valid state.
It's only when it tries to read more that your test would fail, but control has already entered the loop an additional time.
You want to test after reading.
while ( inFile >> firstName >> lastName >> grossPay ){
// ^^ Now the test happens AFTER reading...
cout << firstName << " " << lastName << " " << grossPay << endl;
}

Related

Print number in front of every line of a file

I have made a phone book and the function to add users. I want it to have numbers in front of every line, but I get the wrong number in front of each line. I have added code that prints out the numbers but it gives a big number that is the same on every line. I want it to print like this:
1 John Doe
2 Johnny Doe
3 Max Doe
Right now, it prints this instead:
1878003873 John Doe
1878003873 Johnny Doe
1878003873 Max Doe
I don't know where that number comes from.
void addContact()
{
string Fname, Lname, Address, Contact, list, name, Fname2, Lname2, Address2, Contact2;
int counter, number;
cout << "Enter First Name: ";
getline(cin, Fname);
cout << "Enter Last Name: ";
getline(cin, Lname);
cout << "Enter Address: ";
getline(cin, Address);
cout << "Enter Contact Number: ";
getline(cin, Contact);
ifstream asd("number.txt");
while (asd >> counter >> Fname2 >> Lname2 >> Address2 >> Contact2)
{
number = counter;
}
ofstream adb("number.txt", ios::app);
number = number + 1;
adb << number << " " << Fname << " " << Lname
<< " " << Address << " " << Contact << endl;
}
Suppose that you are adding your first user. What do you think that value of number is going to be then?
ifstream asd("number.txt");
while (asd >> counter >> Fname2 >> Lname2 >> Address2 >> Contact2)
{
number = counter;
}
Because it is your first user then while loop is never entered, so number is never initialised. Hence the garbage numbers you see. Once the first garbage number is there, then the code correctly adds one to each following number.
To fix just add this so that number always gets an initial value.
int counter, number = 0;
Not what you asked about but I think you should close your input file before you try to write the new user
ifstream asd("number.txt");
while (asd >> counter >> Fname2 >> Lname2 >> Address2 >> Contact2)
{
number = counter;
}
asd.close(); // stop reading and close the input file
ofstream adb("number.txt", ios::app);
...
Having a reading and a writing stream open simultaneously on the same file is not a good idea, even if it does seem to work in this case.

C++ Problem with using getline for strings in a text file

I am writing a program that takes a text file and inputs the values from the text file into class functions and a vector. I am using a while loop that uses getline to collect the values from the text file. The issue I am having is that getline functions properly, but only on the second line of the text file. It seems to be either skipping the first line of the file or the first line is somehow overwritten by the second line.
Code as follows
void readContacts(vector<Person>& contacts, ifstream& infile)
{
Person temp;
string line;
cout << " " << endl;
cout << "File opening ... " << endl;
while(getline(infile, line))
{
cout << " " << endl;
infile >> line;
temp.setFirstName(line);
cout << "First Name: " << line << endl;
infile >> line;
temp.setLastName(line);
cout << "Last Name: " << line << endl;
infile >> line;
temp.setPhone(line);
cout << "Phone Number: " << line << endl;
infile >> line;
temp.setEmail(line);
cout << "Email: " << line << endl;
contacts.push_back(temp);
}
}
The text file contains
Kortni Neal 555-555-5555 kdd195#google.com
Aubrey Knight 444-444-4444 akk5#google.com
The console outputs
Welcome to your address book manager!
Please enter a file to read your contacts from (include extension): contacts.txt
File opening ...
First Name: Aubrey
Last Name: Knight
Phone Number: 444-444-4444
Email: akk5#google.com
First Name:
Last Name:
Phone Number:
Email:
File read. Closing the file from read mode.
Menu:
0. Exit
1. Display Address Book
2. Add Contact
What would you like to do?
Thanks for your help.
Yes it does, because the getline() function call reads the first line.
Then you go in and do a infile >> line, which reads starting from the second line.
If you had more lines in your file, you would have seen that it would have skipped every other line .

C++ Spaces are not being read in my input file?

Input txt file:
Joe Smith
Mary Jones
Hamid Namdar
Desired Output Txt file:
Smith Joe
Jones Mary
Namdar Hamid
Output file I receive:
SmitJoeJonesMaryNamdarHamid
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ofstream output;
ifstream input;
string firstname, lastname;
output.open("LastName.txt");
input.open("FirstName.txt");
cout << "Processing Data..." << endl;
input >> firstname >> lastname;
cout << firstname << lastname << endl;
output << lastname << firstname;
cout << lastname << firstname << endl;
input >> firstname >> lastname;
cout << firstname << lastname << endl;
output << lastname << firstname;
cout << lastname << firstname << endl;
input >> firstname >> lastname;
cout << firstname << lastname << endl;
output << lastname << firstname;
cout << lastname << firstname << endl;
input.close();
output.close();
cin.get();
cin.get();
return 0;
}
My program is required to have spaces between the names, and even though there is a space in my text document, the spaces are not being read. Does anyone have an idea on what I should do in order to have the spaces be read?
I am guessing that you would like to see spaces in your output but you are not getting them. That makes you think that the spaces are not being read. The truth is that the white spaces are being read but are being discarded when you use:
input >> firstname >> lastname;
You need to change the lines that create the output to:
cout << firstname << " " << lastname << endl;
output << lastname << " " << firstname << endl;

How to use a loop to read an unknown file size?

So I have this problem.
"write a complete program to read the data in file called "ingolf.txt" when the data looks like this:
78 78 Smith Joe
67 69 Morris Mark
65 88 Kimball Craig
...
73 75 Dennison David
where the 3 dots indicate more lines of data"
This is the loop that I'm using to read the file.
string line;
while(getline(dataFile, line)) {
dataFile >> round1;
dataFile >> round2;
dataFile >> firstName;
dataFile >> lastName;
cout << round1 << " ";
cout << round2 << " ";
cout << firstName << " ";
cout << lastName << " ";
}
When I use this loop, it repeats the last file line twice. Am I doing something wrong?
I used eof() before this and it worked but I read that it's bad practice so I found this loop to use instead. I'm also not sure why I need a variable for this. The file is an unknown size. I'm a beginner so please explain in noob friendly way :D
What you should have is
string line;
while(getline(dataFile, line)) {
istringstream is(line);
is >> round1;
is >> round2;
is >> firstName;
is >> lastName;
// ...
}
In your sample getline() already consumes a line from the input stream, you're stepping into the loop body, and again consume
dataFile >> round1;
dataFile >> round2;
dataFile >> firstName;
dataFile >> lastName;
from the input stream (the next line actually). So you're alternatingly throw away/missing a line of input.
You should either read a line and then parse out the individual fields or read directly into your variables. πάντα ῥεῖ posted an answer showing the first option and here is the second:
while (dataFile >> round1 >> round2 >> firstName >> lastName) {
cout << round1 << " ";
cout << round2 << " ";
cout << firstName << " ";
cout << lastName << " ";
// ...
}
Note that this will work because each field is space-delimited. You'll need a different method if a field can contain whitespace.

splitting a string read from a file/istringstream

I'm currently taking an online C++ class and our current project requires us to read a file, take each student and put it into a vector.
My current problem is splitting the name read and setting it to the right variables.
The professor's pseudo code here:
inputFile.open(sFileName.c_str ());
while(inputFile.fail())
{
cout ERROR OPENING FILE
cout PLEASE REENTER THE PASSWORD OF THE FILE
getline(cin >> wd, sFileName);
inputFile.open(sFileName.c_str());
}
inputFile.clear();
inputFile.seek(0, ios::beg);
while(getline(inputFile, sTemp))
{
istringstream inputSStream(sTemp)
inputSStream >> sFirstName >> sMiddleName >> sLastName >> sID >> sClass;
if(sMiddleName != "|")
sFullName = sFirst name + " " + sMiddleName +" " + sLastName;
else
sFullName = sFirstName + " " + sLastName;
My current code here:
ifstream myFile;
string firstName, middleName, lastName, fullName, studentID, cID;
string inFileName, stringTemp;
cout << "Please enter the name of the file that you want to read in. \n";
cin >> inFileName;
myFile.open(inFileName);
while (myFile.fail())
{
cout << "\n""";
cout << "Error file, Please re-enter file. \n ";
cin >> inFileName;
myFile.open(inFileName);
}
myFile.clear();
myFile.seekg(0, ios::beg);
while (getline(myFile, stringTemp))
{
istringstream inputStream(stringTemp);
inputStream >> firstName >> middleName >> lastName >> studentID >> cID;
if (middleName != "|")
fullName = firstName + " " + middleName + " " + lastName;
else
fullName = firstName + " " + lastName;
//Checking what the input values are
cout << "First name is " << firstName << endl;
cout << "Middle name name is " << middleName << endl;
cout << "Last name is " << lastName << endl;
cout << "studentID is " << studentID << endl;
cout << "CID is " << cID << endl;
Student thisStudent(fullName, studentID, cID);
studentList.push_back(thisStudent);
}
myFile.close();
The current problem is that the line isn't split correctly, first name gets the whole line and mid and last name, studentID and cID all remain empty.
Here is the current file that I'm reading in:
ERIC,ANTHONY,TURNER,1234573,CISC_198
GABRIEL,FEIJO,LOPES,1234574,CISC_199
GEOFFERY,BRYAN,RANSOM,1234575,CISC_200
HANNAH,MAE ,LONGRIE,1234576,CISC_201
HASSAN,ISMAIL,AHMED,1234577,CISC_202
HUNG,B,PHAM,1234578,CISC_203
HUSSEIN,FOUAD,ALJANABI,1234579,CISC_204
JING,XUN,CHEN,1234580,CISC_205
KAJALBEN,CHIMANLAL,MAKWANA,1234581,CISC_206
DANDREA,SHAMAICAH,BUSH,1234570,CISC_195
DANIELLE,MARIE,CORTEZ,1234571,CISC_196
ERDI,T,KIDANE,1234572,CISC_197
AARON,FABIAN,LINGAD,1234567,CISC_192
AARON,T,PATCHIN,1234568,CISC_193
ALI,FOUAD,ALJANABI,1234569,CISC_194
NATHAN,|,NANN,1234585,CISC_210
NEIL,ANDREAS,FRANKA,1234586,CISC_211
OBONE,|,ORIYAVONG,1234587,CISC_212
OLIVIA,JOANNE,MAILANDER,1234588,CISC_213
RALEIGH,|,COSGROVE,1234589,CISC_214
RYAN,PAREDES,PALMARES,1234590,CISC_215
MICHAEL,DUONG,NGUYEN,1234583,CISC_208
MIGLENA,|,CHEMELEKOVA,1234584,CISC_209
STEPHEN,MICHAEL,HOUSE,1234591,CISC_216
MARCUS,D,BUTLER,1234582,CISC_207
Here is the output that I do not understand how to fix.
First name is ERIC,ANTHONY,TURNER,1234573,CISC_198
Middle name name is
Last name is
studentID is
CID is
When you read with operator >> you are splitting on whitespace. Despite the name, getline() can split by other characters than newline:
getline(inputStream, firstName, ',');
getline(inputStream, middleName, ',');
// ...