-3

Is it possible in C++ to use format specifiers in a custom function? Like as in the printf() statement, and how you can use e.g. '%d' to insert an int variable:

printf("The number is %d", num);

But is there a way I can do this with my own function, in C++? Like this:

void output(std::string message)
{
  std::cout << message << '\n';
}

int main()
{
  int num = 123;
  output("The number is %d", num);

  return 0;
}

I tried searching it up, but couldn't really find any result stating that this is possible, so it probably isn't.

I did see something with three dots in a function parameter, a variadic function, but I couldn't figure out if that was what I'm searching for.

Edit: I feel a little bad, maybe I could've just found it with searching a bit better (I didn't know variadic functions were the way to go). See https://en.cppreference.com/w/cpp/utility/variadic. I'm sorry for that.

5
  • 3
    Take a look at std::formatter
    – Barmar
    Commented Jan 24 at 17:56
  • There is no magic that replaces %d with value of num. What printf does is it takes a const char* and variadic arguments, assumes that const char* contains a valid format string and then reads it, finding every % and trying to replace it with next from variadic arguments. If you want to replicate that function, you would need to do the same. Commented Jan 24 at 17:58
  • 3
    you are using C++, we have type-safe variadic templated functions, forget about C unsafe variadic functions. see stackoverflow.com/questions/47941837/c-variadic-template-sum
    – Ahmed AEK
    Commented Jan 24 at 18:07
  • You have the C++23 version std::print("The number is {}", num);. std::print
    – BoP
    Commented Jan 24 at 18:17
  • We all know printf statement... no I have forgotten all about it (actively supressed it... printf is a mess).. last used over 30 years ago in "C". From C++23 we have "std::print" which is far superior (typesafe, less risk of buffer overflows etc.) Commented Jan 24 at 18:33

2 Answers 2

2

You are correct, the "three dots" parameter is what you need. You can use vprintf:

#include <iostream>
#include <cstdarg> // For va_list, va_start, va_end
#include <cstdio>  // For vprintf

void output(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
}

int main() {
    int a = 123;
    output("The number is %d %d\n", a, 456);
    return 0;
}

If you're using C++20 or higher, you can also look at std::format for modern and type-safe placeholding.

0

Yes, you can use vprintf for such purposes.

void output(std::string fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    vnprintf(fmt.c_str(), args);
    va_end(args);
    std::cout << '\n';
}

The strong advice: use std::format since C++20 or {fmt} library.