# Help with ifstream::getline

This topic is 3739 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi Everybody :) I have a question about ifstream::getline Lets say I have the following text file: ------------- 1234567 < this is the first line of the txt file hello world < this is the last line of the txt file ------------- my code is
  std::ifstream ft;
ft.open(...);

char buff[25];
while(!ft.eof())
{
ft.getline(buff,3);
cout<<buff<<endl;

}


At the first iteration of the loop, when getline(buff,3) reads a line which contains more characters than the buffer I have specified, 3, than the next iteration getline(buff,3) does not read anything, i get an empty buffer even though there are more lines, and this loop continues forever. Do I need to clean the buffer or something like that? Thanks

##### Share on other sites
Quote:
 from "The C plus plus Standard Library"If they read lines with more than count-1 characters, they set failbit.

I believe it's std::ios_base::failbit. I would guess it keeps reading the same line over and over?

p.s. why can't I use the plus symbol?!?

##### Share on other sites
If the line is larger than the buffer, the stream will enter a "failed" state when you try to read it. You need to reset this failed state using ft.clear() on your stream. You can detect the failed state by calling ft.fail().

##### Share on other sites
Don't use while(!file.eof()), the end of file bit is set only after a failed read (so your loop will execute one extra time).

while( std::getline(file,input) ) {}

Prefer the use of std::string for strings.

Also, since getline uses the last as the delimiter, but you probably meant to use '3'. If not please specify what you want to do.

##### Share on other sites
Quote:
 Original post by rip-offAlso, since getline uses the last as the delimiter, but you probably meant to use '3'. If not please specify what you want to do.

istream::getline(char*, streamsize) uses the last as the number of characters to be read.

##### Share on other sites
If all you want to do is to read a file and put the contents somewhere, you can use rdbuf(), like:

std::ifstream in("file.txt");  // Initializes the streamstd::cout << in.rdbuf();       // Sends stream read buffer to coutin.seekg(0);                   // Resets to beginning of buffer.in.clear();                    // Clears failbit and eofbit.

That should print the entire contents of "file.txt" verbatim. Drawback is that you
can't check the state of the stream. Always clear() and reset seekg(0) if you want to re-read the file.

Another alternative is to get the info character by character, like:

std::ifstream in("file.txt");  // Initializes the streamchar c;while(in.get(c)){    cout.put(c);}

The above lets you check stream state. Also, unless you really have to, using a character buffer with std::getline(,) instead of a std::string is asking for problems, as mentioned by rip-off.

As ToohrVyk (and rip-off, indirectly) mentioned, use the fail state for your conditional. Something like:

std::ifstream in("file.txt");std::string input;while (!in.fail())  // similarly, rip-off suggested 'while( std::getline(in,input) ){}'{    do something...}

If you have a lot of character or string manipulation, my personal preference is to use file operations as little as possible, and read the contents into a string buffer, and then use string methods for everything else. So you could do something like:

#include <fstream>#include <sstream>#include <string>std::string fileToString(const std::string& filename){    std::ostringstream out;    std::ifstream in(filename.c_str());    out << in.rdbuf();    return out.str();   }std::string strbuf = fileToString("file.txt");

Then you can use the rather rich facilities of std::string to manipulate strbuf. I use the name 'strbuf' loosely here, as it is just a string. This is not to be confused with the standard library 'stringbuf' and 'wstringbuf' that are specializations of the 'basic_stringbuf<>' template class.

--random

[Edited by - random_thinker on September 18, 2007 3:37:15 AM]

##### Share on other sites
Quote:
 Original post by random_thinker#include #include #include std::string fileToString(const std::string& filename){ std::ostringstream out; std::ifstream in(filename.c_str()); out << in.rdbuf(); return out.str(); }std::string strbuf = fileToString("file.txt");Then you can use the rather rich facilities of std::string to manipulate strbuf. I use the name 'strbuf' loosely here, as it is just a string. This is not to be confused with the standard library 'stringbuf' and 'wstringbuf' that are specializations of the 'basic_stringbuf<>' template class.

Better yet,
  #include <fstream>  #include <iterator>  #include <string>  // ...  string fileimage = string(istreambuf_iterator<char>(ifstream(filename.c_str())),                            istreambuf_iterator<char>());

Of course, this doesn't give you the opportunity to check for I/O errors, but it;s as simple as you can get for reading a file into an in-memory image.

##### Share on other sites
Quote:
 Original post by BregmaBetter yet, #include #include #include // ... string fileimage = string(istreambuf_iterator(ifstream(filename.c_str())), istreambuf_iterator());

What beautifully elegant C++ code...fantastic!

--random

##### Share on other sites
Quote:
Original post by ToohrVyk
Quote:
 Original post by rip-offAlso, since getline uses the last as the delimiter, but you probably meant to use '3'. If not please specify what you want to do.

istream::getline(char*, streamsize) uses the last as the number of characters to be read.

Apologies, I must have been thinking of std::getline when I wrote that. [embarrass]

##### Share on other sites

This topic is 3739 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628666
• Total Posts
2984131

• 12
• 10
• 9
• 9
• 10