in.open(filename.c_str(), ifstream::in);
string name, email, group;
while (in >> name >> email >> group) {
in >> name >> email >> group;
cout << name << email << group);
...
}
in.close();
Consider this code where in is of type ifstream and filename is the name of the file from which we read the data. Format of input file is perfectly fine - many lines with 3 string in each.
This piece should simply print all of the data in the file but what id does is printing all of the lines except for the first line. Why is the first line skipped?
Drop in >> name >> email >> group; from the body of the loop. The one in the condition is enough.
You're reading too much.
while (in >> name >> email >> group)
Already reads the data once, the next line reads it again, overwriting your data. Get rid of the repetition and your cout should work just fine.
in.open(filename.c_str(), ifstream::in);
string name, email, group;
while (in >> name >> email >> group) { //Reads the data into the variables
cout << name << email << group; //Outputs the variables.
...
}
in.close();
Consider this line:
while (in >> name >> email >> group) {
each time the program hits this line, it executes the code inside the brackets. In this case, 'in' is read and populates name, email, group even before actually entering the body of the loop.
Thus, when the body of the loop is executed, the first line has already been read.
If you strings are not seperated by new line operator in the input file use code the blow to read it.
ifstream in;
in.open("urfile.txt",ios::beg);
string name, email, group;
while (in.good()) {
in >> name >> email >> group;
cout << name << email << group;
}
in.close();
Related
I am in the middle of a college project which kind of looks like a students' database.
Each line of the text file follows this "model":
age ; full_name ; avg
I need to read the text file and store everything in a vector of structs and I could do that if the name was only one word.
Well, obviously, age is an int, avg is a double, but what about the full name?
I can't just use file >> full_name;, with full_name being a string because it would stop reading to it once it gets to a whitespace. The getline() function would store everything in one place so I am not sure what to do.
Please share your knowlegde with this young mind x)
As many others pointed out, you can use std::getline to read chars till a delimiter.
Consider this snippet of code as a starting point:
int age;
std::string name;
double average;
// ... Open the file which stores the data ...
// then read every line. The loop stops if some of the reading operations fails
while ( input >> age &&
std::getline(input, name, ';') && // consume the first ;
std::getline(input, name, ';') && // read the name
input >> average ) {
// do whatever you need with the data read
cout << "age: " << age << " name: " << name << " average: " << average << '\n';
}
I have a problem with C++ File input.
I have a file with n lines that each lines contains 4 variables. I need them read them into a hash table that I created. My problem is that I can't read the file correct way.
For example here the input file variables:
line id cont uniq-number Band
0 10 B 02020213456 DaftPunk
1 11 A 02030213456 Dazy
and so on..
The main problem is to read each variable in line until file EOF.
So I need read in each line these variables id, cout, uniq-number and band and while it is reading put these data inside a hash table to process them even further in C++.
Example
cout << "File" << endl;
int date,id;
string group,line,ch;
datar d;
hasher h1;
ifstream inFile;
inFile.open("file.txt");
while (getline (inFile,line))
{
// "reads" file each variable
inFile >> id >> ch >> date >> group;
//add these variable in line one to first hash line
d.id = id;
d.data = ch;
d.date= date;
d.group = group;
h1.add(d);
//must repeat until file EOF for each line
}
inFile.close();
In this code,
while (getline (inFile,line))
{
// "reads" file each variable
inFile >> id >> ch >> date >> group;
//add these variable in line one to first hash line
d.id = id;
d.data = ch;
d.date= date;
d.group = group;
h1.add(d);
//must repeat until file EOF for each line
}
the getline reads a line.
Then the loop body reads items from the next line.
Instead of that
inFile >> id >> ch >> date >> group;
do e.g.
istringstream linestream( line );
linestream >> id >> ch >> date;
getline( linestream, group );
The last getline in order to handle possible spaces in a name.
This assumes that the name is last on the line, as it currently is, and it assumes that it's not the case that every second line should be ignored (i.e., that that was bug).
It's also a good idea to add failure checking.
If a stream operation fails then the stream enters a failure state, and you can check that via the member function .fail().
I am trying to read in and then output the contents of a text file with three lines, as follows:
Bob Dylan 10 9
John Lennon 8 7
David Bowie 6 5
For each line, I just want to output the line, i.e. firstName LastName number1 number2.
I'm using the following code for this:
int num1;
int num2;
string firstName;
string lastName;
string fullName;
ifstream inFile;
inFile.open("inputFile.txt");
while (getline(inFile, firstName))
{
inFile >> firstName >> lastName >> num1 >> num2;
fullName = firstName + " " + lastName;
cout << fullName << " " << num1 << " " << num2 << endl;
}
inFile.close();
There are 2 problems with the output from this. First, the first line is not output, although from experimentation I know that it DOES read it in. Second, after the last 2 lines are read in and output (as desired), the program displays everything in the last line EXCEPT the first name (in this case the last thing it prints is Bowie 6 5).
Can someone use this simple example to explain how the getline function works when reading in multiple lines from a file? (I don't even know if it's the best way, but it's the only way I know as of yet). Here are some specific questions.
First, does the while loop conditional getline(inFile, firstName) return a boolean? If so, how can it be true (i.e. how can the while loop start) if I haven't given firstName a value yet? Is it the case that the program reads the first line and if there's something there, then it executes the while loop, but starting with the second line, because it already used the first to check for content?
Second, if firstName does have a value, and if that value is the first name on the first line ("Bob" in this case), why isn't the first line output at all? I've been racking my brain trying to figure out where it went to.
Third, after the program reads in and displays the last two lines, the program moves to the next line and encounters nothing but blanks, right? Then what would be the value of firstName? Would it be blank, or would it still be "David"? If it's blank, why does the while loop execute again? But if it's "David", then why does the program not output that value along with the others?
Btw, I am working out of a textbook (not for homework), and it covers getline, but not for multiple lines. But then the exercises involve multiple lines, so I'm a bit lost.
You are trying to read each line twice.
while (getline(inFile, firstName)) // reads the line
{
// reads the next line and overwrites firstName!
inFile >> firstName >> lastName >> num1 >> num2;
Change it to:
while ( inFile >> firstName >> lastName >> num1 >> num2 )
{
fullName = firstName + " " + lastName;
cout << fullName << " " << num1 << " " << num2 << endl;
}
EDIT: To answer your questions:
How does getline() work?
Reads the entire line up to '\n' character or the delimiting character specified. http://www.cplusplus.com/reference/string/string/getline/?kw=getline
After reading the line, the control goes to the next line in the file.
Also, it returns a boolean value of true if the read operation was successful, else false.
The extraction operator truncates on all whitespaces by default. It also returns a boolean value indicating whether the operation was successful.
I am having trouble getting istringstream to continue in while loop shown below. The data file is shown below also. I use getline from Input file to get the first line and put it in a istringstream lineStream. It passes through the while loop once, then it reads in the second line and goes back to the beginning of the loop and exits rather than continue through the loop. I have no clue why, if anyone could help I would thankful.
EDIT: The reason I have this while loop condition is because the file may contain lines of erroneous data. Therefore, I want to make sure the line I am reading in has the proper form shown below in the data file.
while(lineStream >> id >> safety){//keeps scanning in xsections until there is no more xsection IDs
while(lineStream >> concname){//scan in name of xsection
xname = xname + " " +concname;
}
getline(InputFile, inputline);//go to next xsection line
if(InputFile.good()){
//make inputline into istringstream
istringstream lineStream(inputline);
if(lineStream.fail()){
return false;
}
}
}
Data FILE
4 0.2 speedway and mountain
7 0.4 mountain and lee
6 0.5 mountain and santa
In the presented code, …
while(lineStream >> id >> safety){//keeps scanning in xsections until there is no more xsection IDs
while(lineStream >> concname){//scan in name of xsection
xname = xname + " " +concname;
}
getline(InputFile, inputline);//go to next xsection line
if(InputFile.good()){
//make inputline into istringstream
istringstream lineStream(inputline);
if(lineStream.fail()){
return false;
}
}
}
… the inner declaration of lineStream declares a local object, which ceases to exist when the execution passes out of that block, and which doesn't affect the stream used in the outer loop.
One possible fix is to invert the code a little bit, like this:
while( getline(InputFile, inputline) )
{
istringstream lineStream(inputline);
if(lineStream >> id >> safety)
{
while(lineStream >> concname)
{
xname = xname + " " +concname;
}
// Do something with the collected info for this line
}
}
It seems that it's not separating the word within the space.
Trying to separate the words in between, and stored it in first and second.
cin >> name; //input name
stringstream file (name);
getline(file,first, ' '); //seperate the name with the first name and last name using space
getline(file,second, ' ');
Replace
cin >> name;
with
getline(cin, name); //input name
cin >> reads only upto the first space. You would have realized this if you done a cout << name; to check what's getting read - this is the first step of debugging.
When you read the initial input with cin >> name; that only reads up to the first white space character.
You then try to break that into two pieces at white space, which it doesn't contain.
Easy way:
cin >> first >> second;
Alternatively, if you start with std::getline(cin, name); instead of cin >> name;, then the rest should work correctly.