Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine how many characters `std::getline()` extracted?

Tags:

c++

iostream

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.

like image 756
Slava Avatar asked Dec 08 '18 17:12

Slava


People also ask

Does Getline read delimiter?

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.

Does Getline take \n?

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.

Can Getline have multiple delimiters?

No, std::getline () only accepts a single character, to override the default delimiter. std::getline() does not have an option for multiple alternate delimiters.

How does STD Getline work?

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.


1 Answers

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.

like image 52
Galik Avatar answered Nov 15 '22 04:11

Galik