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;
} 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
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.
"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
"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;
}
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.
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
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
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
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 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.
> 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?
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
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
> 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.
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
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.
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));
>> 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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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...
|
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:";...
|
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...
|
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...
|
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...
| |
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...
|
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...
|
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;
|
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...
|
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,...
|
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...
| |
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,...
|
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...
|
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...
|
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,...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |