So I understand the basic concept of reading a text file line by line using a while loop, now my question is how do I read each line and then put the contents of those lines into a variable that is part of a structure?
I figured out how to write my text to a file but not how to store the information from that same file so here is what I have so far but it does not seem to work:
This works:
void save(string fileName)
{
Container *traverser = list;
ofstream file;
file.open(fileName);
while (traverser != NULL){
file << traverser->student->getFirstName() << endl;
file << traverser->student->getLastName() << endl;
file << traverser->student->getGrade() << endl;
file << traverser->student->getEdu() << endl;
traverser = traverser->next;
}
}
This doesn't:
void load(string fileName)
{
Container *traverser;
Container* c;
Student *s;
string fname, lname;
int grade;
int edu;
ifstream file;
file.open(fileName);
string line;
while (getline(file, line)){
file >> fname;
file >> lname;
file >> grade;
file >> edu;
s = new Student(fname, lname, grade, edu);
c = new Container();
c->student = s;
}
}
Is it something with my syntax or am I doing it wrong all together?
The program essentially asks for the students first and last names, grade, and education then it stores that into a text file, then it is supposed to load the information from the text file back into the program (I didn't post the whole code because there is a lot).
Thanks!
Additional info: list is a linked list of Structures (students)
I suspect your data is in one line
while (getline(file, line)){
istringstream lstr(line);
lstr >> fname;
lstr >> lname;
lstr >> grade;
lstr >> edu;
s = new Student(fname, lname, grade, edu);
c = new Container();
c->student = s;
}
This could already do the job.
Edit: You might want to #include <sstream>
Related
I need to read a line of a text file and each word is seperated by a single space. The line stores the id, firstname, lastname, department, and gpa in that order. A line in the text file looks like this:
9528951 Adney Smith CS 4.2 //id fname lname dept gpa
main.cpp:
int main()
{
// Add your code here:
string line;
stringstream ss(line);
ifstream myfile("enroll_test.txt");
HashTable<string> ht;
string id, fname, lname, dept, gpa;
if (!myfile.is_open())
{
cout << "File failed to open" << endl;
return 0;
}
while (getline(myfile, line))
{
ss >> id >> fname >> lname >> dept >> gpa;
Student<string> student;// = new Student(fname, lname, gpa, dept);
student.setFirstName(fname);
student.setLastName(lname);
student.setGPA(gpa);
student.setDepartment(dept);
// id = line.substr(0, line.find(" "));
ht.insert(id, student);
}
myfile.close();
ht.displayHash();
// else cout << "Unable to open file";
return 0;
}
The error I am getting is:
terminate called after throwing an instance of 'std::invalid_argument'
what(): stoi
When I run the debugger it shows the error happens when I try to insert into the hashTable. It takes me string_conversion.h and throws the invalid argument. In the debugger there are no values set for the student variables so I believe I used ss stream wrong to read the line and parse. Anyone know how I can solve this? By the way I am using stoi() to convert the id to an int the rest can be left as strings.
I tried using ss stream but I dont believe I am implementing it right.
your error is probably because id is an empty string because ss was never filled.
string line;
stringstream ss(line);
this just constructs ss with an initial value of a copy of the string in line which is empty.
while (getline(myfile, line))
{
ss >> id >> fname >> lname >> dept >> gpa;
the data is in line, but it won't be in ss as it was only a copy of line initial value, so just pass line to ss to consume it on every line.
while (getline(myfile, line))
{
ss << line;
ss >> id >> fname >> lname >> dept >> gpa;
Edit: as noted by #user4581301 , this won't clear the content of ss on every loop iteration, so you should instead construct ss inside your loop.
while (getline(myfile, line))
{
istringstream ss(line);
ss >> id >> fname >> lname >> dept >> gpa;
and remove its definition from the top of the code.
I need to split up a line coming in from a file. The file contains a list of books with an id, Author, published date, and title.
91507 Lewis Carroll 1865 Alice in Wonderland
The author name I can just split up into first and last, but what about the title?? I have no idea how to deal with that. Should I just create a second file so I can use getline?
I am a newb and I don't understand how to use stringsteam for this, or split() or anything like that, so if that is what you suggest could you please explain what's happening? I haven't understood any of the examples I've looked at well enough to modify them to suit my purpose.
ifstream fin;
fin.open(filename)
string id;
string first;
string last;
string year;
string title;
if(fin.is_open())
{
while(!fin.eof())
{
fin >> id >> first >> last >> year;
getline(fin, title);
cout << first << " " << last << " " << title << endl;
}
fin.close();
}
Do this:
#include <fstream>
using namespace std;
int main()
{
ifstream fin("somefile.txt");
string id = "";
string authFirst = "";
string authLast = "";
string date = "";
string title = "";
string temp = "";
fin >> id >> authFirst >> authLast >> date >> title;
getline(fin, temp);
title += temp;
cout << title << endl;
return 0;
}
My vector is not getting data from the file I have it retrieve. I created a class called Student, and needed to make a vector out of it to store multiple values for the students. The code worked on my original test file, but when I change the students, it errors out.
Here's the part that's in main:
vector<Student> studentVector; //creating a vector using the defined class Student
string userFile = "";
string filename = "";
int numStudents = 0; //total number of students
int numQuestions = 0; //total number of questions
string key = ""; //answer key
cout << "Enter the name of the file: ";
cin >> userFile; //get name of file from user
filename = checkFile(userFile, numQuestions, key); //gets info from file and returns the new file name to get student answers
fillVector(studentVector, filename, numStudents); //fills vector with values from file
Here's the function that reads the data:
void fillVector(vector<Student>& newStudentVector, string filename, int& numStudents) {
ifstream studentAnswers; //read mode file
string line = ""; //used to read lines
int id = 0;
string fName = ""; //first name
string lName = ""; //last name
string answers = "";
studentAnswers.open(filename); //opens file using filename passed into function
while (getline(studentAnswers,line)) {
++numStudents; //reads the number of lines in file
}
studentAnswers.close(); //closed file because it reached end of file
studentAnswers.open(filename); //reopens file
for (int i = 0; i < numStudents; i++) {
//reads file data
studentAnswers >> id;
studentAnswers >> fName;
studentAnswers >> lName;
studentAnswers >> answers;
Student newStudent(id, (fName + " " + lName), answers, 100.00, "A"); //creates a new object
newStudentVector.push_back(newStudent); //adds new vector with newStudent data
}
studentAnswers.close(); //close file
}
You have to open your string-name file like this :
studentAnswers.open(filename.c_str());
Try to loop through your vector like this :
getline(studentAnswers,line)
while (!studentAnswers.eof()) {
getline(studentAnswers,line)
++numStudents;
}
Assuming that you've implemented operator>>(std::istream&, Student&), then a fairly easy way to implement fillVector() is to use stream iterators.
void fillVector(std::vector<Student>& newStudentVector,
std::string filename, int& numStudents) {
std::ifstream studentAnswers(filename);
if (!studentAnswers) {
std::cout << "WARNING! studentAnswers file not found\n";
}
newStudentVector.assign(
std::istream_iterator<Student>(studentAnswers),
std::istream_iterator<Student>());
numStudents = newStudentVector.size();
}
I am trying to read in a text file that has a name and age on each line such as this
Tom
55
Bob
12
Tim
66
I then need to pass it to a function which takes in a string and an int such as:
sortDLL.Insert(name, age);
However, I am unsure how to do this. I tested it out with the following and it works (bypassing the text file):
string tom = "tom";
string bob = "bob";
string tim = "tim";
int a = 55;
int b = 12;
int c = 66;
sortDLL.Insert(tom, a);
sortDLL.Insert(bob, b);
sortDLL.Insert(tim, c);
But when I try to read in the text file and send it, the program doesn't run properly. This is what I am currently trying, and I have messed around with a few other things, but have had no luck:
ifstream infile ("names.txt");
while(getline(infile, line));
{
istringstream ss(line);
if (ss >> name)
cin >> name;
else if (ss >> wt)
cin >> wt;
sortDLL.Insert(name, wt);
}
infile.close();
Like always, any help to get this to work would be greatly appreciated, thanks!
I think the correct code should look like this. Remember you have to read 2 line per 1 insert.
while(getline(infile, line))
{
stringstream ss(line);
ss >> wt;
if(ss.fail()) {
name = line;
continue;
}
else {
// cout << name << ":" << wt << endl;
sortDLL.Insert(name, wt);
}
}
I know this post has been made before on stack overflow, and I have combined various tutorials; but why does this code cause an error on execution - it does compile.
void leaderBoard::loadFromFile(void)
{
string line;
ifstream leaderBoardFile ("leaderboard.data");
vector<string> playerInfoVector;
if (leaderBoardFile.is_open())
{
while ( leaderBoardFile.good() )
{
playerInfoVector.clear();
getline (leaderBoardFile,line);
std::string input = line;
std::istringstream ss(input);
std::string token;
//cout << line << endl;
while(getline(ss, token, ',')) {
//for current line;
playerInfoVector.push_back(token);
}
string firstName = playerInfoVector.at(0);
string stringAge = playerInfoVector.at(1);
string stringScore = playerInfoVector.at(2);
//int age;
//stringstream(stringAge) >> age;
//int score;
//stringstream(stringScore) >> score;
//addScore(firstName,age,score);
////stringstream(stringAge) >> age;
////Add text to vector (push back)
playerInfoVector.clear();
}
leaderBoardFile.close();
}
else cout << "Unable to open file";
}
Yes loads of times
while ( leaderBoardFile.good() )
{
playerInfoVector.clear();
getline (leaderBoardFile,line);
should be
while ( getline (leaderBoardFile,line) )
{
playerInfoVector.clear();
It is incredible how many times this error is repeated. You actually got it right in your second while loop, so why wrong in the first one?
Unfortunately some tutorials also get this wrong.
It would also be sensible to add a check that you really do have three items in your vector. Something like this
if (playerInfoVector.size() < 3)
{
cerr << "Not enough items in player info vector\n";
exit(1);
}
string firstName = playerInfoVector.at(0);
string stringAge = playerInfoVector.at(1);
string stringScore = playerInfoVector.at(2);