DEV Community

Discussion on: How do I use variable-arguments (varargs) in C++ (effectively)?

 
omercsp profile image
Omer • Edited

I apologize for criticizing the way you ask questions, but it's important. Knowing how to ask the right questions is an important tool for a developer. The fact is - you asked a question, and that is what you got an answer for. Then you asked another question, and got an answer for that one too. Now , on the third iteration, you ask another different question (still not clear, though).

Dude, this is not how you get work done.

Regardless:

if I want anything done right in C++, I have to do it myself

and

At this point, I might as well figure out how to make it myself (which I was, hence the question about varargs in C++).
Since apparently C++ is shit at providing actual format-strings.

Usually wrong. For C++, as well of most of the mature languages. If a language provides you the facility to do something, you need a very very good reason to not use it for the same task. So far, no such reason was provided.

I need to capture the string here, which I could technically do, since std::string(char const*) constructor exists.
But, there's a problem here, I one, need to provide my own memory for the C-string provided to the first argument (I don't know if this applies to the var-args), which means I can't do char* b = "Hello, %s!"; sprintf(/* ... */);.
On top of that, I also have my format string saved in an std::string, and as I've tested, passing in std::string.c_str() (char const*) to sprintf is apparently a no-no (invalid conversion from char* to const char*).

It looks like you got the sprintf arguments somewhat mixed up. This is how sprintf is declared (cleaned up a bit for clarity):

int sprintf (char *buff, const char *format, ...);

  • 1st argument is the target buffer, which is required to be mutable. So you must pass it a char array. For this, argument, std::string will not work. You need a proper char based buffer.

  • The 2nd argument, the format, is const char*, which means a std::string::c_strwill be perfect for it. Hence, code like this:

    char buff[256];
    std::string fmt = "%s%d";
    std::sprintf(buff, fmt.c_str(), "abc", 5);
    std::cout << buff << std::endl;
Enter fullscreen mode Exit fullscreen mode

is fine.

This has nothing to do with var-args. It's just the way this function is defined.

[sprintf is used here but NEVER usesprintf. ALWAYS use snprintf)]

I want to be able to pass a string with any string formatters into a function, ans pass in a variable number of arguments, and get a formatted string returned. With this method, I have a static amount of inputs for the format (basically, the opposite of a variable amount*).

This is probably the closest you got to describe your real problem (though still pretty vague, some code will probably help). If I got it right this time, you can find some answers here: stackoverflow.com/questions/234216.... Note the C++11 solution in the first answer formats the string twice, so it's robust and correct, but not very efficient in terms runtime(not a problem unless you write time sensitive application).

You can see that answers given there (unless you use C++20), are around the concepts I layered out during this discussion. You can dislike it all you want, but it's like that for a reason. Reinventing the wheel will usually give you grief, not joy.

And regarding your side question:

(Why does the above code work w/o std::? - Can C++ resolve identifiers if there aren't multiple w/ the same name in diff namespaces?)

Roughly speaking, C++ is a superset of C, thus any valid C is valid C++ code. Since printf(...() (without the std:: prefix) is valid C, any C++ compiler should be able to build it. In reality, there are some corner cases C code fails a C++ build, but 99% of the time, it's fine. In gcc 10, for example, printf and its friends defined within the std namespace following using statements for them (using std::printf and so), so you get the printf in the global namespace for free.

Thread Thread
 
baenencalin profile image
Calin Baenen

I apologize for criticizing the way you ask questions, but it's important. Knowing how to ask the right questions is an important tool for a developer.

Eh, criticism isn't something I treat with negativity, thanks for pointing out the flaw I only partially recognize.
Sorry for the "question hopping".

I'd say I got a bit carried away with trying to find a "best" way of string-formatting, and as of C++20, I found it std::format -- That's essentially everything I want and all I need.

Thread Thread
 
baenencalin profile image
Calin Baenen

I'd say I got a bit carried away with trying to find a "best" way of string-formatting, and as of C++20, I found it std::format -- That's essentially everything I want and all I need.

I tried looking for how to format strings in C++ before, but this never really came up to surface (I use DuckDuckGo). All I get is stringstream and snprintf/printf solutions.