Вопрос по c++, c – Как передать переменное число аргументов в printf / sprintf

72

У меня есть класс, который содержит «ошибку» функция, которая отформатирует некоторый текст. Я хочу принять переменное количество аргументов, а затем отформатировать их с помощью printf.

Example:

class MyClass
{
public:
    void Error(const char* format, ...);
};

Метод Error должен принимать параметры, вызывать printf / sprintf для его форматирования, а затем что-то делать с ним. Я не хочу писать все форматирование самостоятельно, поэтому имеет смысл попытаться выяснить, как использовать существующее форматирование.

Ваш Ответ

7   ответов
0

Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceeded

31

#include <stdio.h>
#include <stdarg.h>

void Error (char * format, ...)
{
  char buffer[256];
  va_list args;
  va_start (args, format);
  vsnprintf (buffer, 255, format, args);


  //do something with the error

  va_end (args);
}
vsnprintfError: User Rate Limit Exceeded
Error: User Rate Limit Exceededsizeof(buffer)Error: User Rate Limit Exceeded
2

void Log(LPCWSTR pFormat, ...) 
{
    va_list pArg;
    va_start(pArg, pFormat);
    char buf[1000];
    int len = _vsntprintf(buf, 1000, pFormat, pArg);
    va_end(pArg);
    //do something with buf
}
5

#include <sstream>
#include <boost/format.hpp>
#include <iostream>
using namespace std;

class formatted_log_t {
public:
    formatted_log_t(const char* msg ) : fmt(msg) {}
    ~formatted_log_t() { cout << fmt << endl; }

    template <typename T>
    formatted_log_t& operator %(T value) {
        fmt % value;
        return *this;
    }

protected:
    boost::format                fmt;
};

formatted_log_t log(const char* msg) { return formatted_log_t( msg ); }

// use
int main ()
{
    log("hello %s in %d-th time") % "world" % 10000000;
    return 0;
}

int x = SOME_VALUE;
double y = SOME_MORE_VALUE;
printf( "some var = %f, other one %f", y, x ); // no errors at compile time, but error at runtime. compiler do not know types you wanted
log( "some var = %f, other one %f" ) % y % x; // no errors. %f only for compatibility. you could write %1% instead.
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3

ка.

C ++ Передача переменного количества аргументовError: User Rate Limit Exceeded

There's no way of calling (eg) printf without knowing how many arguments you're passing to it, unless you want to get into naughty and non-portable tricks.

The generally used solution is to always provide an alternate form of vararg functions, so printf has vprintf which takes a va_list in place of the .... The ... versions are just wrappers around the va_list versions.

Error: User Rate Limit Exceeded

void Error(const char* format, ...)
{
    char dest[1024 * 16];
    va_list argptr;
    va_start(argptr, format);
    vsprintf(dest, format, argptr);
    va_end(argptr);
    printf(dest);
}
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededBOOMError: User Rate Limit Exceeded
132
Bad
void Error(const char* format, ...)
{
    char dest[1024 * 16];
    va_list argptr;
    va_start(argptr, format);
    vsprintf(dest, format, argptr);
    va_end(argptr);
    printf(dest);
}

1024*16printf вызов может столкнуться с проблемами, еслиdestprintf("%s", dest)vprintf или жеvfprintf:

Good
void Error(const char* format, ...)
{
    va_list argptr;
    va_start(argptr, format);
    vfprintf(stderr, format, argptr);
    va_end(argptr);
}

vsnprintf вместоvsprintf. vsnprintf

3

The first parameter must give some indication of the number of parameters that follow. So in printf(), the "format" parameter gives this indication - if you have 5 format specifiers, then it will look for 5 more arguments (for a total of 6 arguments.) The first argument could be an integer (eg "myfunction(3, a, b, c)" where "3" signifies "3 arguments)

Then loop through and retrieve each successive argument, using the va_start() etc. functions.

Похожие вопросы