Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading directly from an std::istream into an std::string

Is there anyway to read a known number of bytes, directly into an std::string, without creating a temporary buffer to do so?

eg currently I can do it by

boost::uint16_t len;
is.read((char*)&len, 2);
char *tmpStr = new char[len];
is.read(tmpStr, len);
std::string str(tmpStr, len);
delete[] tmpStr;
like image 277
Fire Lancer Avatar asked Nov 29 '09 18:11

Fire Lancer


People also ask

How do I read an Istream file?

Other ways to read a std::istreamTo read a line of input, try the getline() function. For this, you need #include <string> in addition to #include <iostream> . To read a single char: use the get() method. To read a large block of characters, either use get() with a char[] as the argument, or use read() .

How do you read from a file to a string C++?

Read whole ASCII file into C++ std::string If(f) Declare another variable ss of ostringstream type. Call rdbuf() fuction to read data of file object. Put the data of file object in ss. Put the string of ss into the str string.

What does std::string () do?

std::string class in C++ C++ has in its definition a way to represent a sequence of characters as an object of the class. This class is called std:: string. String class stores the characters as a sequence of bytes with the functionality of allowing access to the single-byte character.

How do I read a whole file in CPP?

File Handling in C++Create a stream object. Connect it to a file on disk. Read the file's contents into our stream object. Close the file.


3 Answers

std::string has a resize function you could use, or a constructor that'll do the same:

boost::uint16_t len;
is.read((char*)&len, 2);

std::string str(len, '\0');
is.read(&str[0], len);

This is untested, and I don't know if strings are mandated to have contiguous storage.

like image 130
GManNickG Avatar answered Oct 17 '22 13:10

GManNickG


You could use a combination of copy_n and an insert_iterator

void test_1816319()
{
    static char const* fname = "test_1816319.bin";
    std::ofstream ofs(fname, std::ios::binary);
    ofs.write("\x2\x0", 2);
    ofs.write("ab", 2);
    ofs.close();

    std::ifstream ifs(fname, std::ios::binary);
    std::string s;
    size_t n = 0;
    ifs.read((char*)&n, 2);
    std::istream_iterator<char> isi(ifs), isiend;
    std::copy_n(isi, n, std::insert_iterator<std::string>(s, s.begin()));
    ifs.close();
    _unlink(fname);

    std::cout << s << std::endl;
}

no copying, no hacks, no possibility of overrun, no undefined behaviour.

like image 29
dex black Avatar answered Oct 17 '22 15:10

dex black


You could use something like getline:

#include <iostream>
#include <string>
using namespace std;

int main () {
  string str;
  getline (cin,str,' ');
}
like image 2
rmn Avatar answered Oct 17 '22 15:10

rmn