If I don't know the size a string will be, and if that size may change later, and if that string may contain '0' characters, what methods are there to do this? (I would prefer a professional/reliable method if possible)

Dani AI

Generated

std::string is the professional, reliable choice here — it is resizable, stores its characters contiguously, and can contain embedded NUL ('\0') bytes because length is tracked separately from any terminator. It also offers constructors/assign/replace overloads that accept a pointer+length so embedded zeros are preserved (for example std::string s("ab\0cd", 5);). This matches ' suggestion and gives full std::library ergonomics (resize, append, move, allocators). (en.cppreference.com)

If the intent is “raw bytes” rather than text, a byte container such as std::vector<char> or std::vector<uint8_t> is a perfectly valid alternative: owning, resizable, and explicit about size semantics (no C-string assumptions). That follows ' idea and is often clearer when passing binary buffers around. (en.cppreference.com)

Watch out for API expectations: c_str() returns a null-terminated pointer, and since C++11 data()/c_str() are specified to provide the same contents; however std::string_view is a non-owning view whose data() is not guaranteed to be null-terminated, so it is unsafe to hand a string_view::data() to a C API that expects a C-style string. When calling C-style functions, either use the c_str() (or pass pointer+length) or use an API that accepts an explicit length. (en.cppreference.com)

A fixed array like char buf[BUFSIZ] is okay for quick examples but fragile in real code: BUFSIZ is the stdio library's buffer-size macro (used for buffering), not a guaranteed maximum string length — 's idea is pragmatic, and 's correction is correct. Prefer dynamic containers and read/write functions that accept a size. Example patterns:

std::string s("ab\0\0cd", 6);
std::ofstream out("out.bin", std::ios::binary);
out.write(s.data(), s.size());

Use resize + read or container data()/size() when doing binary I/O. (pubs.opengroup.org)

Recommended Answers

All 4 Replies

std::string ?

If you don't want to use std::string for some reason, then you could use a std::vector< char >, or something like that. Or, you could make your own, simple struct for keeping a pointer to an array of char and a size:

struct StringWithNulls
{
    char* chars;
    unsigned size;
};

I would use std::string unless you have a really good reason though (as vmanes said).

You could declare a char[BUFSIZ]. It is a max length your system can use. Not exactly what you are describing, but it would get the job done.

You could declare a char[BUFSIZ]. It is a max length your system can use.

Um...no. BUFSIZ is a macro representing the size of the default buffer used by the stdio library. It's nearly always a great deal less than the maximum length string you could define. BUFSIZ also doesn't preclude you from using a longer string with the stdio library, it's only there to give the library something to work with when the programmer doesn't provide a buffer with setbuf(). And the buffer is only used for performance purposes within the library, functionality doesn't change even when stdio is unbuffered.

However, BUFSIZ is usually large enough to represent a reasonable default buffer size for the programmer. Common values are 512 and 1024, so if you want something "finite, but large enough" in less than robust programs, BUFSIZ is often an acceptable choice. I use it for test and example programs regularly. ;)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.