std::ifstream ft;
ft.open(...);
char buff[25];
while(!ft.eof())
{
ft.getline(buff,3);
cout<<buff<<endl;
}
Help with ifstream::getline
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
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
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?!?
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().
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).
Instead use the read operation itself in the condition:
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.
Instead use the read operation itself in the condition:
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.
Quote:Original post by rip-off
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.
istream::getline(char*, streamsize) uses the last as the number of characters to be read.
If all you want to do is to read a file and put the contents somewhere, you can use rdbuf(), like:
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:
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:
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:
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]
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]
Quote:Original post by random_thinker#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.
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.
Quote:Original post by Bregma
Better yet,#include <fstream> #include <iterator> #include <string> // ... string fileimage = string(istreambuf_iterator<char>(ifstream(filename.c_str())), istreambuf_iterator<char>());
What beautifully elegant C++ code...fantastic!
--random
Quote:Original post by ToohrVykQuote:Original post by rip-off
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.
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]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement