Reputation: 376
Alright, this is for a project that's supposed to read in some code from a file with information on a student. However, it doesn't seem to be reading in anything from the file. I'm working in Visual Studio, and when I run it and pause at the end, I look at the vector I've created and it says there are no students in it. Student is a class I've created.
ifstream input;
string student_file;
cin >> student_file;
input.open(student_file);
double id_number = 0;
while (input >> id_number)
{
string name = "";
string address = "";
string phone_number = "";
cin.sync();
getline(input, name);
cin.sync();
getline(input, address);
cin.sync();
getline(input, phone_number);
Student * s = new Student(id_number, name, address, phone_number);
students.push_back(s);
}
The student class should be set up properly with a constructor and everything, so I'm assuming it's this code that's giving me the trouble. Even some direction on whether the problem is with the loop or my use of getlines would be helpful. Thanks!
Upvotes: 0
Views: 127
Reputation: 96845
This line:
while (input >> id_number)
extracts the integer from the input stream into id_number
. When the extraction is finished, the newline character is still left in the stream. std::getline()
is programmed to terminate extraction upon the discovery of the newline character (among other specifications).
To circumvent this situation, you need to discard the newline by using the std::ws
manipulator. std::ws
discards only leading whitespace from the stream. Newlines are considered whitespace. It is also advised that you check that your input succeeded by encasing the extraction in an if
statement:
if (std::getline(input >> std::ws, name) && std::getline(input >> std::ws, address) && std::getline(input >> std::ws, phone_number))
Notice that I've also removed the std::cin.sync()
between calls. Syncing the input buffer is not necessary in this context as stream insertion is not being performed, thus changes to the external sequence don't need to be regarded. Besides, the idea of syncing the input buffer of std::cin
is non-nonsensical as std::cin
is not affected whatsoever by the actions being taken on input
.
And lastly, your vector that holds the student pointers should instead hold the actual objects themselves. This avoids the need for using dynamic memory allocation. The type of the vector should therefore be std::vector<Student>
. And this is how you would construct the element in the vector:
students.emplace_back(id_number, name, address, phone_number);
Here is the full code:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ifstream input;
std::string student_file;
std::cin >> student_file;
input.open(student_file);
double id_number = 0;
std::vector<Student> students;
while (input >> id_number)
{
string name;
string address;
string phone_number;
if (std::getline(input >> std::ws, name) &&
std::getline(input >> std::ws, address) &&
std::getline(input >> std::ws, phone_number))
{
students.emplace_back(id_number, name, address, phone_number);
}
}
}
Upvotes: 3