Let's say I read a std::string
from std::istream
by using std::getline()
overload. How to determine how many characters extracted from the stream? std::istream::gcount()
does not work as discussed here: ifstream gcount returns 0 on getline string overload
#include <iostream>
#include <sstream>
#include <string>
int main()
{
std::istringstream s( "hello world\n" );
std::string str;
std::getline( s, str );
std::cout << "extracted " << s.gcount() << " characters" << std::endl;
}
Live example
Note, for downvoters - length of the string is not the answer, as std::getline()
may or may not extract additional character from the stream.
The getline() function extracts characters from the input stream and appends it to the string object until the delimiting character is encountered. If no delimiter is specified, the default is the newline character at the end of the line. The input value does NOT contain the delimiter.
Your cin >>N stops at the first non-numeric character, which is the newline. This you have a getline to read past it, that's good. Each additional getline after that reads the entire line, including the newline at the end.
No, std::getline () only accepts a single character, to override the default delimiter. std::getline() does not have an option for multiple alternate delimiters.
std::getline (string)Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, '\n', for (2)). The extraction also stops if the end of file is reached in is or if some other error occurs during the input operation.
It would seem the way to do this is not completely straightforward because std::getline
may (or may not) read a terminating delimiter and in either case it will not put it in the string. So the length of the string is not enough to tell you exactly how many characters were read.
You can test eof()
to see if the delimiter was read or not:
std::getline(is, line);
auto n = line.size() + !is.eof();
It would be nice to wrap it up in a function but how to pass back the extra information?
One way I suppose is to add the delimiter back if it was read and let the caller deal with it:
std::istream& getline(std::istream& is, std::string& line, char delim = '\n')
{
if(std::getline(is, line, delim) && !is.eof())
line.push_back(delim); // add the delimiter if it was in the stream
return is;
}
But I am not sure I would always want that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With