473,508 Members | 2,226 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

getline and EOF question

I'm trying to read a whole file as a single string, using the getline()
function, as in the example below. I can't tell what I'm doing wrong.
Tried g++ 3.2, 3.4 and 4.0. Thanks!
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>

using namespace std;

int main(int argc, char * argv[])
{
const int MAX_SIZE=100000;
string s;
char chars[MAX_SIZE];

fstream IN("junk", ios::in);

// These 2 are ok.
IN.getline(chars, MAX_SIZE, EOF); // works, so EOF ok
getline(IN, s, 'x'); // works with string, no EOF

// g++ doesn't like this one.
getline(IN, s, EOF); // what's wrong??

return 0;
}

Jul 23 '05 #1
18 8223
Amadeus W. M. wrote:
I'm trying to read a whole file as a single string, using the getline()
function, as in the example below. I can't tell what I'm doing wrong.
Tried g++ 3.2, 3.4 and 4.0. Thanks!
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>

using namespace std;

int main(int argc, char * argv[])
{
const int MAX_SIZE=100000;
string s;
char chars[MAX_SIZE];

fstream IN("junk", ios::in);

// These 2 are ok.
IN.getline(chars, MAX_SIZE, EOF); // works, so EOF ok
getline(IN, s, 'x'); // works with string, no EOF

// g++ doesn't like this one.
getline(IN, s, EOF); // what's wrong??

return 0;
}


Unfortunately, there is a std::getline() declared as follows:

template<class charT, class traits, class Allocator>
basic_istream<charT,traits>& getline(basic_istream<charT,traits>& is,
basic_string<charT,traits,Allocator>& str, charT delim);

It wants a charT which is not of the same type as EOF. Try calling the
getline on IN. I have not tried that myself, so I don't know if it will
help.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #2
On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:
Amadeus W. M. wrote:
I'm trying to read a whole file as a single string, using the getline()
function, as in the example below. I can't tell what I'm doing wrong.
Tried g++ 3.2, 3.4 and 4.0. Thanks!
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>

using namespace std;

int main(int argc, char * argv[])
{
const int MAX_SIZE=100000;
string s;
char chars[MAX_SIZE];

fstream IN("junk", ios::in);

// These 2 are ok.
IN.getline(chars, MAX_SIZE, EOF); // works, so EOF ok
getline(IN, s, 'x'); // works with string, no EOF

// g++ doesn't like this one.
getline(IN, s, EOF); // what's wrong??

return 0;
}


Unfortunately, there is a std::getline() declared as follows:

template<class charT, class traits, class Allocator>
basic_istream<charT,traits>& getline(basic_istream<charT,traits>& is,
basic_string<charT,traits,Allocator>& str, charT delim);

It wants a charT which is not of the same type as EOF. Try calling the
getline on IN. I have not tried that myself, so I don't know if it will
help.


I did, in the very program I posted, and it worked. I was curious why the
one on string wouldn't work.

There is also a getline() in bits/basic_string.h

template<typename _CharT, typename _Traits, typename _Alloc>
basic_istream<_CharT,_Traits>&
getline(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);

So in this version, the type of the delimiter must be the same _CharT
as in basic_istream and basic_string. The same is true for the istream
version of getline. So I don't understand why one works and the other
doesn't. What's the type of EOF? Whatever the type, it should both work,
or both not work.
Jul 23 '05 #3

"Amadeus W. M." <am*******@cablespeed.com> wrote in message
news:pa****************************@cablespeed.com ...
I'm trying to read a whole file as a single string, using the getline()
function, as in the example below. I can't tell what I'm doing wrong.
Tried g++ 3.2, 3.4 and 4.0. Thanks!
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>

using namespace std;

int main(int argc, char * argv[])
{
const int MAX_SIZE=100000;
string s;
char chars[MAX_SIZE];

fstream IN("junk", ios::in);

// These 2 are ok.
IN.getline(chars, MAX_SIZE, EOF); // works, so EOF ok
getline(IN, s, 'x'); // works with string, no EOF

// g++ doesn't like this one.
getline(IN, s, EOF); // what's wrong??

return 0;
}


Here is a small example of one way to read the entire file. The key to
answering your question is checking the state of the stream. Once you have
read the last line of the file, it is the next call to getline() that will
set the eof flag of ifl.

#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
ifstream ifl("junk");
string s, temp;
while ( 1 )
{
getline(ifl, temp);
if (ifl.eof()) break;
s += temp + "\n"; // if you want to maintain line breaks
}
cout << "// starts on next line\n";
cout << s;
cout << "// ended on last line\n";
return 0;
}

On an aside, if you just want to read the entire contents of the file,
perhaps consider using read() on a binary file stream. You can open it at
the end of the file to deduce the size in bytes of the file. Then seek back
to the beginning and call read().

Thanks,
Kyle
Jul 23 '05 #4
"Amadeus W. M." <am*******@cablespeed.com> wrote in
news:pa****************************@cablespeed.com :
I'm trying to read a whole file as a single string, using the getline () function, as in the example below. I can't tell what I'm doing wrong.
Tried g++ 3.2, 3.4 and 4.0. Thanks!

If the objective is to read a file into a string, the
code below is handy and instructive. It does not use
getline.

/*
From: Robert W Hand <rw****@NOSPAMoperamail.com>
Newsgroups: alt.comp.lang.learn.c-c++
Subject: Re: Reading a file into a string?
Date: Wed, 30 Mar 2005 21:18:08 -0500

*/
#include <iostream>
#include <fstream>
#include <istream>
// #include <sstream>
#include <string>
#include <iterator>

int main(int argc, char *argv[]) {
if(argc != 3) {
std::cerr << "Usage: " << argv[0] << " InputFile OutputFile" <<
std::endl;
return 1;
}
std::ifstream fin(argv[1], std::ios::in);
if(fin.bad() ) {
std::cerr << "Could not open" << argv[1] << "for reading." <<
std::endl;
return 1;
}
std::ofstream fout(argv[2], std::ios::out | std::ios::binary);
if(fout.bad() ) {
std::cerr << "Could not open" << argv[2] << "for writing." <<
std::endl;
return 1;
}

fin.unsetf(std::ios_base::skipws);
std::istream_iterator<char> in(fin);
std::istream_iterator<char> out;
std::string buf(in, out); // Problem Line for bcc
fout << buf;
fin.close();
fout.close();

return 0;
}
Jul 23 '05 #5
On Fri, 01 Jul 2005 02:14:51 -0400, Amadeus W. M. wrote:
I'm trying to read a whole file as a single string, using the getline()
function, as in the example below. I can't tell what I'm doing wrong.
Tried g++ 3.2, 3.4 and 4.0. Thanks!
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>

using namespace std;

int main(int argc, char * argv[])
{
const int MAX_SIZE=100000;
string s;
char chars[MAX_SIZE];

fstream IN("junk", ios::in);

// These 2 are ok.
IN.getline(chars, MAX_SIZE, EOF); // works, so EOF ok
getline(IN, s, 'x'); // works with string, no EOF

// g++ doesn't like this one.
getline(IN, s, EOF); // what's wrong??

return 0;
}

std::getline(IN, s, (char) EOF); // works.

The std is necessary, because there's a C version in stdlib.h:

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

and the compiler thinks I'm trying to call that one. Also, without the
cast to char, EOF is being treated as int. Don't know though why I don't
have to cast it in the stream version of getline.

So there, reading a file into a string can be done in one instruction.

Jul 23 '05 #6
Amadeus W. M. wrote:
On Fri, 01 Jul 2005 02:14:51 -0400, Amadeus W. M. wrote:
I'm trying to read a whole file as a single string, using the getline()
function, as in the example below. I can't tell what I'm doing wrong.
Tried g++ 3.2, 3.4 and 4.0. Thanks!
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>

using namespace std;

int main(int argc, char * argv[])
{
const int MAX_SIZE=100000;
string s;
char chars[MAX_SIZE];

fstream IN("junk", ios::in);

// These 2 are ok.
IN.getline(chars, MAX_SIZE, EOF); // works, so EOF ok
getline(IN, s, 'x'); // works with string, no EOF

// g++ doesn't like this one.
getline(IN, s, EOF); // what's wrong??

return 0;
}

std::getline(IN, s, (char) EOF); // works.

The std is necessary, because there's a C version in stdlib.h:

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

and the compiler thinks I'm trying to call that one. Also, without the
cast to char, EOF is being treated as int. Don't know though why I don't
have to cast it in the stream version of getline.

So there, reading a file into a string can be done in one instruction.


Just be aware that this may work for text files, but probably
won't work for binary files - where "(char) EOF" (0xff) may
appear within the binary file.

Larry
Jul 23 '05 #7
Amadeus W. M. wrote:
On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:
Amadeus W. M. wrote:
I'm trying to read a whole file as a single string, using the getline()
function, as in the example below. I can't tell what I'm doing wrong.
Tried g++ 3.2, 3.4 and 4.0. Thanks!
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>

using namespace std;

int main(int argc, char * argv[])
{
const int MAX_SIZE=100000;
string s;
char chars[MAX_SIZE];

fstream IN("junk", ios::in);

// These 2 are ok.
IN.getline(chars, MAX_SIZE, EOF); // works, so EOF ok
getline(IN, s, 'x'); // works with string, no EOF

// g++ doesn't like this one.
getline(IN, s, EOF); // what's wrong??

return 0;
}
Unfortunately, there is a std::getline() declared as follows:

template<class charT, class traits, class Allocator>
basic_istream<charT,traits>& getline(basic_istream<charT,traits>& is,
basic_string<charT,traits,Allocator>& str, charT delim);

It wants a charT which is not of the same type as EOF. Try calling the
getline on IN. I have not tried that myself, so I don't know if it will
help.


I did, in the very program I posted, and it worked.


What you posted was using an array of char with the member function. I
tried passing a string to the member function, and it didn't work. I
believe it could be made to work if the size of the file were passed to
getline, but I'm not sure how to get the size of the file, and haven't
found time to look into it.
I was curious why the one on string wouldn't work.
In terms of the Standard, I believe my reply explained that. Don't you
agree?
There is also a getline() in bits/basic_string.h

template<typename _CharT, typename _Traits, typename _Alloc>
basic_istream<_CharT,_Traits>&
getline(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);
I don't recommend looking in bits for definitive answers to the C++ Standard
Library API, but it can be instructive in both gaining a better
understanding of the API, and seeing how it is implemented.
So in this version, the type of the delimiter must be the same _CharT
as in basic_istream and basic_string. The same is true for the istream
version of getline. So I don't understand why one works and the other
doesn't. What's the type of EOF? Whatever the type, it should both work,
or both not work.


The errors I'm getting are suggesting that EOF is type int. You could try
casting to char or something, but that doesn't seem like a portable
solution, even if it does work. As to why it works in one case and not the
other, I would really have to examine all the signatures. I've extracted
most of the Standard Headers from the Standard, and created source code
files. Unfortunately there are a few remaining to be done. Among them are
some of the IO headers.

Just as a guess, the could be a case where a template is being used in one
circumstance, and not the other. Templates do not support type conversion
in the same was as do comperable built in types.

As for whether it /should/ work for both or neither, I agree that is
desirable, but I don't believe the Standard dictates that, and it may be an
unreasonable expectation of the implementers. I haven't seen a function
signature in the Standard that would necessarily work for any form using
EOF. If it does work in one circumstance, that's just luck of the draw.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #8
Amadeus W. M. wrote:
On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:
Unfortunately, there is a std::getline() declared as follows:

template<class charT, class traits, class Allocator>
basic_istream<charT,traits>& getline(basic_istream<charT,traits>& is,
basic_string<charT,traits,Allocator>& str, charT delim);

It wants a charT which is not of the same type as EOF. Try calling the
getline on IN. I have not tried that myself, so I don't know if it will
help.


I did, in the very program I posted, and it worked. I was curious why the
one on string wouldn't work.


One thing I neglected to mention in previous replies - but which I suspect
we both agree upon - is that getline() is really not intended to be used in
this way, and there are better means of reading in a whole file. This
discussion is merely "academic". Do you agree?

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #9
Steven T. Hatton wrote:
Amadeus W. M. wrote:
On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:
Unfortunately, there is a std::getline() declared as follows:

template<class charT, class traits, class Allocator>
basic_istream<charT,traits>& getline(basic_istream<charT,traits>& is,
basic_string<charT,traits,Allocator>& str, charT delim);

It wants a charT which is not of the same type as EOF. Try calling the
getline on IN. I have not tried that myself, so I don't know if it will
help.

I did, in the very program I posted, and it worked. I was curious why the
one on string wouldn't work.


One thing I neglected to mention in previous replies - but which I suspect
we both agree upon - is that getline() is really not intended to be used in
this way, and there are better means of reading in a whole file. This
discussion is merely "academic". Do you agree?


The istream methods read() and readsome() would seem to be better
choices for the task.

Larry
Jul 23 '05 #10
What you posted was using an array of char with the member function. I
tried passing a string to the member function, and it didn't work.
Why would you expect it to work, if the prototype of the
istream::getline() is

istream& getline( char* buffer, streamsize num );
istream& getline( char* buffer, streamsize num, char delim );

string is not char*.
I believe it could be made to work if the size of the file were passed
to getline, but I'm not sure how to get the size of the file, and
haven't found time to look into it.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <inttypes.h>
#include <sys/stat.h>
#include <unistd.h>

using namespace std;

int main(int argc, char * argv[])
{

// Use the stat system call.
struct stat status;
stat(argv[1], &status);
std::cout << status.st_size << std::endl;

// Alternatively, use seekg+tellg
size_t pos;
fstream IN;

IN.open(argv[1], ios::in | ios::binary);
IN.seekg(0, ios::end);
pos = IN.tellg();
IN.seekg(0, ios::beg); // or IN.close();
cout << pos << endl;

return 0;
}

I was curious why the one on string wouldn't work.


In terms of the Standard, I believe my reply explained that. Don't you
agree?


What's the standard got to do with it? I'm not saying the standard if
violated. In

istream::getline(char*, streamsize, char delim);

EOF is treated as char, whereas in

std::getline(istream&, string &, char delimiter='\n');

EOF is treated as int (as you noticed). Notice that I used
IN.getline(...), with fstream IN. Now fstream is an instantiation of
basic_fstream to char:

pwd
/usr/include/c++/3.4.0
grep fstream * | grep typedef | grep -v wchar
iosfwd: * typedef basic_ifstream<char> ifstream;
iosfwd: typedef basic_ifstream<char> ifstream; ///< @isiosfwd
iosfwd: typedef basic_ofstream<char> ofstream; ///< @isiosfwd
iosfwd: typedef basic_fstream<char> fstream; ///< @isiosfwd

So then istream::getline() is not templated, and int to char is implicit.
On the other hand, std::getline is templated, and the conversion is not
implicit. Your intuition was right.
Just as a guess, the could be a case where a template is being used in one
circumstance, and not the other. Templates do not support type conversion
in the same was as do comperable built in types.

Jul 23 '05 #11
> One thing I neglected to mention in previous replies - but which I suspect
we both agree upon - is that getline() is really not intended to be used in
this way, and there are better means of reading in a whole file. This
discussion is merely "academic". Do you agree?


To paraphrase a famous president: it depends what the meaning of the word
"better" is. If by better you mean faster/more efficient, then of course,
I agree.

But e.g. for ASCII files of size=O(10k) on which you want to do
some find-and-replace, putting the entire file in a string in single
instruction is a pretty darn good way of doing it.

I don't suppose anyone in their right mind would try to read a 1G vob file
in a string, would they?
Jul 23 '05 #12
Amadeus W. M. wrote:
What you posted was using an array of char with the member function. I
tried passing a string to the member function, and it didn't work.


Why would you expect it to work, if the prototype of the
istream::getline() is

istream& getline( char* buffer, streamsize num );
istream& getline( char* buffer, streamsize num, char delim );

string is not char*.
I believe it could be made to work if the size of the file were passed
to getline, but I'm not sure how to get the size of the file, and
haven't found time to look into it.


#include <iostream>
#include <fstream>
#include <cstdlib>
#include <inttypes.h>
#include <sys/stat.h>
#include <unistd.h>

using namespace std;

int main(int argc, char * argv[])
{

// Use the stat system call.
struct stat status;
stat(argv[1], &status);
std::cout << status.st_size << std::endl;

// Alternatively, use seekg+tellg
size_t pos;
fstream IN;

IN.open(argv[1], ios::in | ios::binary);
IN.seekg(0, ios::end);
pos = IN.tellg();
IN.seekg(0, ios::beg); // or IN.close();
cout << pos << endl;

return 0;
}

I was curious why the one on string wouldn't work.


In terms of the Standard, I believe my reply explained that. Don't you
agree?


What's the standard got to do with it? I'm not saying the standard if
violated. In

istream::getline(char*, streamsize, char delim);

EOF is treated as char, whereas in

std::getline(istream&, string &, char delimiter='\n');

EOF is treated as int (as you noticed). Notice that I used
IN.getline(...), with fstream IN. Now fstream is an instantiation of
basic_fstream to char:

pwd
/usr/include/c++/3.4.0
grep fstream * | grep typedef | grep -v wchar
iosfwd: * typedef basic_ifstream<char> ifstream;
iosfwd: typedef basic_ifstream<char> ifstream; ///<
@isiosfwd
iosfwd: typedef basic_ofstream<char> ofstream; ///<
@isiosfwd
iosfwd: typedef basic_fstream<char> fstream; ///<
@isiosfwd

So then istream::getline() is not templated, and int to char is implicit.
On the other hand, std::getline is templated, and the conversion is not
implicit. Your intuition was right.
Just as a guess, the could be a case where a template is being used in
one
circumstance, and not the other. Templates do not support type
conversion in the same was as do comperable built in types.


Strange. In both cases the type of the delimiter is actually specified as a
template parameter. In the case of std::basic_istream<> it's a template
parameter of the class. In the std::getline() it's a template parameter of
the function. I'm not sure why one works and not the other.

In /usr/include/c++/3.3.5/string, bits/basic_string.h is the file being
#included. That means the std::getline in question is declared as follows:

template<typename _CharT, typename _Traits, typename _Alloc>
basic_istream<_CharT,_Traits>&
getline(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);

Now /usr/include/c++/3.3.5/istream defines basic_istream like this:

template<typename _CharT, typename _Traits>
class basic_istream : virtual public basic_ios<_CharT, _Traits>
{
public:
// Types (inherited from basic_ios (27.4.4)):
typedef _CharT char_type;

//...

__istream_type&
getline(char_type* __s, streamsize __n, char_type __delim);
//...
};
The error message I get is this:

test.cpp: In function `int main(int, char**)':
test.cpp:21: error: invalid conversion from `void*' to `char**'
test.cpp:21: error: cannot convert `std::string' to `size_t*' for argument
`2'
to `__ssize_t getline(char**, size_t*, FILE*)'//wth is this?

That makes me believe its trying to use std::istream::getline(). When I
explicitly wrote std::getline(IN, s, EOF);

I got:
test.cpp: In function `int main(int, char**)':
test.cpp:21: error: no matching function for call to `getline(std::fstream&,
std::string&, int)'
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #13
Larry I Smith wrote:
Steven T. Hatton wrote:
Amadeus W. M. wrote:
On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:
Unfortunately, there is a std::getline() declared as follows:

template<class charT, class traits, class Allocator>
basic_istream<charT,traits>& getline(basic_istream<charT,traits>& is,
basic_string<charT,traits,Allocator>& str, charT delim);

It wants a charT which is not of the same type as EOF. Try calling the
getline on IN. I have not tried that myself, so I don't know if it will
help.
I did, in the very program I posted, and it worked. I was curious why the
one on string wouldn't work.


One thing I neglected to mention in previous replies - but which I
suspect we both agree upon - is that getline() is really not intended to
be used in
this way, and there are better means of reading in a whole file. This
discussion is merely "academic". Do you agree?


The istream methods read() and readsome() would seem to be better
choices for the task.

Larry

This is my choice:

ifstream in("filename");
stringstream ss;
ss << in.rdbuf();
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #14
> Strange. In both cases the type of the delimiter is actually specified as a
template parameter. In the case of std::basic_istream<> it's a template
parameter of the class. In the std::getline() it's a template parameter of
the function. I'm not sure why one works and not the other.
Now you understand my confusion. Read my previous post more carefully.
fstream is in fact an instantiation of basic_fstream to char, so
istream::getline() is just a regular function now, and so the implicit
conversion from int to char of EOF. However, std::getline remains
templated, and the type of EOF must match that of string, and they don't.

The error message I get is this:

test.cpp: In function `int main(int, char**)': test.cpp:21: error:
invalid conversion from `void*' to `char**' test.cpp:21: error: cannot
convert `std::string' to `size_t*' for argument `2'
to `__ssize_t getline(char**, size_t*, FILE*)'//wth is this?


I explained this before: it's the C-version of getline. The compiler
finds this one first and complains. It will work if you use std::getline.

Jul 23 '05 #15
Amadeus W. M. wrote:
Strange. In both cases the type of the delimiter is actually specified
as a
template parameter. In the case of std::basic_istream<> it's a template
parameter of the class. In the std::getline() it's a template parameter
of
the function. I'm not sure why one works and not the other.


Now you understand my confusion. Read my previous post more carefully.
fstream is in fact an instantiation of basic_fstream to char, so
istream::getline() is just a regular function now, and so the implicit
conversion from int to char of EOF. However, std::getline remains
templated, and the type of EOF must match that of string, and they don't.


Hey, I just checked the dates on some of my first C++ work since I got
serious about it, I can only claim about 12 mos of solid C++ experience.
What you posted was a bit cryptic for me.

I believe what you are saying is that the compiler doesn't have to figure
out what char means when it process the function call because it already
did that when it compiled the template for fstream. The instantiated
template is just another class at this point. Right?
The error message I get is this:

test.cpp: In function `int main(int, char**)': test.cpp:21: error:
invalid conversion from `void*' to `char**' test.cpp:21: error: cannot
convert `std::string' to `size_t*' for argument `2'
to `__ssize_t getline(char**, size_t*, FILE*)'//wth is this?


I explained this before: it's the C-version of getline. The compiler
finds this one first and complains. It will work if you use std::getline.


--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #16
Amadeus W. M. wrote:

std::getline(IN, s, (char) EOF); // works.

The std is necessary, because there's a C version in stdlib.h:

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

and the compiler thinks I'm trying to call that one.
std::getline is a function template:
template<class charT, class traits, class Allocator>
basic_istream<charT, traits>& getline(
basic_istream<charT, traits>&,
basic_string<charT, traits, Allocator>&,
charT delim );

If you call it with parameters:
basic_istream<char, traits>
basic_string<char, traits, Allocator>
int

as you have done, then the compiler cannot match this to that
particular function template. It won't automatically try
and convert 'int' to everything to see if it does get a match.

So it tries to match your call to the non-template version of
getline, and reports its failures there. (This is the
behaviour mandated by the C++ standard; although some compilers
will be friendly and warn you that it failed to match the
template version too).
Also, without the cast to char, EOF is being treated as int.
EOF is an int that is returned by the C standard IO functions
in <cstdio>.

EOF is not a char. It is never returned by any C++ stream I/O
functions, and cannot be passed as a parameter to them. In fact
it has nothing to do with stream I/O at all.
Don't know though why I don't have to cast it in the stream
version of getline.
Usually EOF is defined to be -1. So your call looks like this:
std::getline(IN, s, -1);

This reads from IN into the string 's', until it encounters
the character -1 (usually the byte 255).
If your file didn't contain this character, then it would
appear to read until the end of file.
So there, reading a file into a string can be done in one instruction.


A more robust way:

std::ostringstream oss;
oss << IN.rdbuf();

Then oss.str() returns the string.

Another good way is the method suggested by Peter Gordon.

Jul 23 '05 #17
Peter Gordon wrote:

fin.unsetf(std::ios_base::skipws);
std::istream_iterator<char> in(fin);
std::istream_iterator<char> out;
std::string buf(in, out); // Problem Line for bcc
fout << buf;
fin.close();
fout.close();


BCC 5.5.1 has a bug with its std::string constructors.
Don't know if it's fixed in later versions.
You can use this instead:

std::string buf;
std::copy(in, out, std::back_inserter(buf));

Jul 23 '05 #18
>> Don't know though why I don't have to cast it in the stream
version of getline.


Usually EOF is defined to be -1. So your call looks like this:
std::getline(IN, s, -1);


I meant istream::getline(). This also expects a char as its 3rd argument
(delimiter), and it's also templated ;)
How come it accepts EOF, which is int? That was my question here.

Thanks for the answer, very thorough! And the rdbuf() call is very handy
too.


Jul 23 '05 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
6033
by: seia0106 | last post by:
Hello I am writing a function to read a binary file. Here is a part of code #include <fstream> .. .. BYTE *pData; long lDataLen; pms->GetPointer(&pData); lDataLen = pms->GetSize(); // Read...
8
1413
by: max | last post by:
Hi, I've tried the std::getline and std::string. It seams to work but I get some tourbles with it. WIth the folowing code: if(ne_menu=='4') { cout << "Nom du Client/Projet:";...
5
7726
by: vknid | last post by:
Hello, I have a question. Its probably a very newbish question so please be nice hehe. =D I have been reading through C++ Programming Fundamentals, and have come a crossed an example program...
1
2133
by: ma740988 | last post by:
Consider: ifstrem MyFile("extractMe.txt"); string Str; getline(MyFile, Str); getline above extracts the contents of MyFile and place into the string object. Deduced using FROM/TO logic I...
10
5590
by: Skywise | last post by:
I keep getting the following error upon compiling: c:\c++ files\programs\stellardebug\unitcode.h(677) : error C2664: 'class istream &__thiscall istream::getline(char *,int,char)' : cannot convert...
14
3856
by: KL | last post by:
I am so lost. I am in a college course for C++, and first off let me state I am not asking for anyone to do my assignment, just clarification on what I seem to not be able to comprehend. I have a...
42
6741
by: mellyshum123 | last post by:
I need to read in a comma separated file, and for this I was going to use fgets. I was reading about it at http://www.cplusplus.com/ref/ and I noticed that the document said: "Reads characters...
11
427
by: Key9 | last post by:
Hi all This is an simple app : read cin and print to cout I want it's action like "cat" with out arguement. #include <iostream> #include <string> using namespace std;
8
3525
by: toton | last post by:
Hi, I am reading some large text files and parsing it. typical file size I am using is 3 MB. It takes around 20 sec just to use std::getline (I need to treat newlines properly ) for whole file in...
0
7225
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7123
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7326
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7383
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7046
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5627
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3194
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3182
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
766
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.