Returning to Beginning of File After Getline

Returning to beginning of file after getline

Since you have reached (and attempted to read past) the end of the file, the eof and fail flags will be set. You need to clear them using ifile.clearthen try seeking:

ifile.clear();
ifile.seekg(0);

How do I return an ifstream back to the beginning of a line that was just read in C++?

There is no direct way to say "get back to the start of the last line". However, you can get back to a position you kept by using std::istream::tellg(). That is, before reading a line you'd use tellg() and then seekg() to get back to the position.

However, calling the seek functions frequently is fairly expensive, i.e., I would look at removing the requirement to read lines again.

C++ getline function missing the first line of txt file

You create a single node so every iteration through the loop you overwrite the previously read values.

In the second iteration of the while loop your first call to getline presumably fails and sets the value of name to an empty string. As the stream is now in a failed state the rest of your reads are ignored and finally the loop breaks at the end of the loop.

This might be closer to what you wanted:

    int recordCount = 0;
fs.open(fileName, ios::in | ios::binary);
while(fs) {
record * temp = new record;
std::getline(fs, temp->name);
std::getline(fs, temp->email);
std::getline(fs, temp->address);
fs >> temp->phoneNo;
if (!fs) {
// Reading failed, delete the temporary and exit the loop
delete temp;
break;
}
std::getline(fs, dummy);
recordCount++;

if(head == NULL){
head = temp;
previous = temp;
tail = temp;
} else {
previous->next = temp;
previous = temp;
tail = temp;
}

}

Your code could be made memory leak safer by using smart pointers to ensure temp is never leaked even if exceptions are thrown.

How to go back to the beginning of a file after reaching .eof() in C++?

OK, it works. The trick is call

file.clear();
file.seekg(0, ios::beg);

just after the iteration. Sorry :(

What's actually happens when we try to extract line in file after which `eof` character is present with istream::getline() and std::getline()

To quote the standard, section 21.3.3.4 inserters and extractors [string.io]:

Clause 6:

[…] After constructing a sentry object, if the sentry converts to true, calls str.erase() and then extracts characters from is and appends them to str […] until any of the following occurs:

  • end-of-file occurs on the input sequence (in which case, the getline function calls is.setstate(ios_base::eofbit)).
  • […]

Section 29.7.4.1.3 Class basic_istream::sentry:

explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);
Effects: If is.good() is false, calls is.setstate(failbit)
[…]
If, after any preparation is completed, is.good() is true, ok_ != false otherwise, ok_ == false. During preparation, the constructor may call setstate(failbit)
[…]

explicit operator bool() const;
Returns: ok_

So, what is happening with the string version:

  1. You extract the last string. This sets eofbit, but not failbit
  2. You getline again
  3. getline constructs a sentry
  4. The sentry checks is.good(). This is false because eofbit is set
  5. The sentry sets the failbit and sets its member ok_ to false
  6. The getline function checks if the sentry is true (operator bool). This is false
  7. The getline function returns before clearing your old string

Section 29.7.4.3 Unformatted input functions

Clause 21 (this is about the C-string version):

In any case, if n is greater than zero, it then stores a null character (using charT()) into the next successive location of the array

The rest of the wording is similar to the string version. In other words, the C-string version of getline always stores a '\0' character, even if it failed. The std::string version does not, presumably because it doesn't introduce the same memory safety issues that you have with the C version if you forget to check the failbit.

Using getline() with file input in C++

getline, as it name states, read a whole line, or at least till a delimiter that can be specified.

So the answer is "no", getlinedoes not match your need.

But you can do something like:

inFile >> first_name >> last_name >> age;
name = first_name + " " + last_name;

C++ - std::getline() returns nothing

You don't need to invoke file.open(filename); because you already opened the file using the constructor std::ifstream file(filename);.

Invoking file.open(filename); after opening the file using the constructor causes the stream to enter an error state, because the file has not been closed yet.

See The difference between using fstream constructor and open function.



Related Topics



Leave a reply



Submit