Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the C++ idiom to replace snprintf(3)?

Tags:

c++

I have some C++ code which needs to generate an error message when parsing a certain file header fails. In this case, I need to ensure that a certain 4 byte field in the header is "OggS", and if it is not, return an error message like "invalid capture_pattern: 'FooB'; expecting 'OggS'". My code looks something like this:

const string OggPage::parseHeader(void) {
  read(fd, capture_pattern, sizeof(capture_pattern)); // error handling omitted
  if (strncmp(capture_pattern, CAPTURE_PATTERN, sizeof(capture_pattern)) != 0) {
    char err[256];
    snprintf(err, sizeof(err), "Failed to read %d bytes from file descriptor %d: %s\n", sizeof(capture_pattern), fd, err);
    return err;
  }

  return "Everything was A-OK!";
}

What is the standard C++ idiom for building a string from other datatypes? I'm not wedded to the printf(3)-style format here, so feel free to suggest anything that works.

like image 373
Josh Glover Avatar asked Feb 24 '23 08:02

Josh Glover


2 Answers

You can use stringstream or ostringstreamfrom C++ Standard library. If further stream will not be used to read values from it (e.g. it's istream part won't be used) ostringstream is more suitable.

#include <sstream>
#include <string>
#include <iostream>

int main() {
 std::stringstream str_stream;
 int number = 5;

 str_stream << " String with number " << number << std::endl;;

 std::string str = str_stream.str();
 std::cout << str; 
}
like image 100
beduin Avatar answered Mar 09 '23 11:03

beduin


Just as a note, please don't suggest replacements for the actual reading--there is a reason that I want to use the C standard library for I/O here. :)

You can't really ask for "idiomatic" ways to do something in C++, and then say "but I want to stick to the C standard library...

Anyway, you have three options. I don't believe any of them is idiomatic (because that would imply some kind of consensus about this being the best way):

  • stick with the C APIs you're already using
  • Use the the C++ std::stringstream, which is part the iostreams section of the standard library
  • use Boost.Format

The latter has the downside that it relies on a third-party library, but the advantage that it gives you printf-like syntax, in a typesafe and extensible manner, which interoperates cleanly with C++ streams.

like image 34
jalf Avatar answered Mar 09 '23 13:03

jalf