Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ std::istream readsome doesn't read anything

It's like readsome isn't even reading. Returns 0 and doesn't read any chars. What is wrong here?

#include <fstream>
#include <iostream>

int main ()
{
  std::fstream stream("list.cpp", std::ios::in);

  if (stream.good() || !stream.bad() || stream.is_open()) {

    std::cout << "Well, stream looks good." << std::endl;

    char justOneChar = 'L';
    auto ssize = stream.readsome(&justOneChar, 1);

    std::cout << ssize << " : " << justOneChar << std::endl;
  }

  return -1;
}

Output:

Well, stream looks good. 0 : L

like image 820
Samuel Danielson Avatar asked Nov 24 '14 05:11

Samuel Danielson


3 Answers

auto ssize = stream.readsome(&justOneChar, 1);

1 is the maximum number of characters to read. If the streams internal buffers are empty when you call it, you'll get back zero as a return value.

The following quote (with my bold) shows this aspect:

streamsize readsome (char* s, streamsize n);

Extracts up to n characters from the stream and stores them in the array pointed by s, stopping as soon as the internal buffer kept by the associated stream buffer object (if any) runs out of characters, even if the end-of-file has not yet been reached.

The function is meant to be used to read data from certain types of asynchronous sources that may eventually wait for more characters, since it stops extracting characters as soon as the internal buffer is exhausted, avoiding potential delays.

It's basically a way to get as many characters as are available (subject to your specified limit) without having to wait for the stream to provide more.

like image 146
paxdiablo Avatar answered Sep 28 '22 03:09

paxdiablo


Consulting a reference,

The behavior of this function is highly implementation-specific. For example, when used with std::ifstream, some library implementations fill the underlying filebuf with data as soon as the file is opened (and readsome() on such implementations reads data, potentially, but not necessarily, the entire file), while other implementations only read from file when an actual input operation is requested (and readsome() issued after file opening never extracts any characters). Likewise, a call to std::cin.readsome() may return all pending unprocessed console input, or may always return zero and extract no characters.

In short, readsome is fairly useless, at least for standard streams. It's a super-nonblocking read: it will only load data that has been buffered in the user-level process, and it will not ever make a kernel call.

like image 31
Potatoswatter Avatar answered Sep 28 '22 02:09

Potatoswatter


It doesn't work because there might not be any characters available for reading at that instant. It works as a non-blocking read function as someone mentioned, therefore this means that it doesn't wait for input, which is why it wasn't asking you for input. So for you to use it to successfully read anything, there must be something available in the underlying buffer.

To see the number of characters that can be extracted in the next call to readsome, use the in_avail function.

like image 22
smac89 Avatar answered Sep 28 '22 02:09

smac89