2017-02-17 2 views
-1

Ищу сделать небольшой регистратор должен использоваться следующим образом:Как использовать varargs для малого регистратора?

logger log; 
const char* text = "World"; 
log.write("Hello %s", text); 
log.write("Step %d", 1); 

Это мой код, который не работает правильно:

class logger 
{ 
public: 
    void write(const char* msg, ...) 
    { 
     FILE* file = fopen("c:/test.txt", "a"); 
     if(file != NULL) 
     { 
      va_list args; 
      va_start(args, msg); 
      fprintf(file, "%s\n", msg, args); 
      va_end(args); 
      fclose(file); 
     } 
    } 
}; 

Это то, что я получаю:

Hello %s 
Step %d 

Я так и не использовал varargs, поэтому не уверен, правильно ли я использую его.

+2

C не имеет классов или спецификаторов доступа. Не просто пометьте случайным образом. – StoryTeller

+1

Это будет очень медленно, если вы откроете и закроете файл для каждой отдельной печати. –

+0

@StoryTeller: в любом случае это решение C, а не C++. – Kobe

ответ

3

Вы считаете, что C ведет себя аналогично Java или Python или другим языкам, которые могут «разбить» аргумент массива на функцию, которая принимает varargs, но C не настолько сложна. Когда вы передаете аргументы fprintf, C буквально подталкивает значение args (переменную типа va_list) в стек. Вместо этого вам нужно нажать на содержание аргументов в стек.

Или вместо этого вы можете использовать функцию, которая принимает параметр va_list в качестве параметра. Эта функция - vprintf (и друзья vsprintf, vfprintf и т. Д.).

У вас есть еще одна проблема, которая заключается в том, что вы используете параметр «msg» вызывающего абонента, используя «% s», но, судя по всему, ожидая, что fprintf будет рекурсивно использовать результат как строку формата и fprintf для аргументов. Это не сработает. Вместо этого просто используйте msg в качестве строки форматирования.

 va_list args; 
     va_start(args, msg); 
     vfprintf(file, msg, args); 
     fputc('\n', file); 
     va_end(args); 
Смежные вопросы