4

I'd like to read a binary file and use something like std::string that automatically resizes the buffer and such.

I'm using Visual C++. What are my options?

4
  • Do you want to read the whole file into an std::string? Commented Oct 7, 2009 at 21:34
  • He is basically asking for a binary safe string. Is std::string is binary safe? Commented Oct 7, 2009 at 21:36
  • 2
    why use a std::string for a binary file? Commented Oct 7, 2009 at 21:40
  • 1
    Try std::vector<char> instead Commented Nov 19, 2009 at 15:47

5 Answers 5

11

The std::string class already does handle data with embedded NUL characters. What problem are you encountering?

Note that when using the .c_str() method, any embedded NUL character will terminate the returned C-style string.

Sign up to request clarification or add additional context in comments.

4 Comments

Ah, problem I was having was using the += operator to append a char* to the string. Best to use .assign() and .append().
What eaxactly do you mean with "any embedded NUL character will terminate the returned C-style string" ? .c_str() will return all characters of the std::string, and then an extra \0. It's not like .c_str() stops copying characters after the first \0. Of course, if you ONLY have that const char*, you won't know which \0 is the last one.
@MSalters: all the implementations of std::string that I'm familiar with don't actually copy anything on .c_str() (who would free it?). The problem is not .c_str() itself, but whatever function you pass it to next; for example strlen() would of course stop at the first NUL.
there are additional concerns. e.g. str.append(buf, 0 , sizeof buf); seems to only append up to the first nul character in buf. After the .append() here I gathered from the docs (wrongly) that str.size() would return sizeof buf more than before the .append() ..
9

std::string should be safe to do so... you only have to be careful using .c_str() method. Use .data().

2 Comments

-1, you don't even know if the internal representation is in contiguous memory (depends on the implementation), so data() is very dangerous
Yes, I do (as long as the library is standards-compliant). C++ Standard, point 21.3.6.3: "If size() is nonzero, the member [data() const] returns a pointer to the initial element of an array whose first size() elements equal the corresponding elements of the string controlled by *this."
6

You can always use std::vector<unsigned char> v (or whatever type of input you expect) and then to get at the buffer you simply &v[0] and v.size() for the size.

1 Comment

With C++11, I would suggest using v.data() instead of &v[0].
4

Yes you can have embedded nulls in your std::string.

Example:

std::string s; s.push_back('\0'); s.push_back('a'); assert(s.length() == 2); 

Note: std::string's c_str() member will always append a null character to the returned char buffer; However, std::string's data() member may or may not append a null character to the returned char buffer.

Be careful of operator+=

One thing to look out for is to not use operator+= with a char* on the RHS. It will only add up until the null character.

For example:

std::string s = "hello"; s += "\0world"; assert(s.length() == 5); 

The correct way:

std::string s = "hello"; s += std::string("\0world", 6); assert(s.length() == 11); 

Storing binary data more common to use std::vector

Generally it's more common to use std::vector to store arbitrary binary data.

std::vector<char> buf; buf.resize(1024); char *p = &buf.front(); 

It is probably more common since std::string's data() and c_str() members return const pointers so the memory is not modifiable. with &buf.front() you are free to modify the contents of the buffer directly.

Comments

0

std::string allows NUL characters so you can just go ahead and use that.

There is no problem with using c_str() or data(). Yes, the embedded NULs will be in your data, but if you don't use them to terminate your strings (you'll need to call length() to find out how many bytes are in your string) then all will be good.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.