2016-04-27 3 views
1

Я пытался передать переменные аргументы другой функции в C, но это вызывает противоречивый результат в другой среде выполнения, а также в различных работает в том же среде:Переходя va_list к другим функциям

int main() 
{ 
    int result = myprintf("Something \n %d", 9); 
    return result; 
} 

int myprintf(const char *format, ...){ 
    printf("Something \n %d", 9); 
    printf("\n"); 
    va_list args;   
    va_start(args, format);  
    int result = printf(format,args); 
    printf("\n"); 
    va_end(args); 
    return result; 
} 

а также полученный результат:

WWW.FIRMCODES.COM 
9 
WWW.FIRMCODES.COM 
438656664 

Не удалось найти причину "438656664".

+1

Вы не можете этого сделать; вы можете передать 'args' только функции, которые принимают' va_args' как аргумент. У них есть 'v' на свое имя:' vprintf', 'vfprintf',' vsnprintf'. –

+0

В случае, если мне нужно создать оболочку поверх функции printf(), то как я могу продолжить? Я думал, что могу создать функцию, и после некоторой манипуляции с строкой формата я буду вызывать printf(). Но, как вы сказали, я должен назвать семейство функций «v», верно? – Monk

+0

Да, пересылка 'va_list' в' v' семейство функций - это путь. Вы, вероятно, не должны манипулировать строкой формата, хотя, по крайней мере, не сами спецификаторы формата. (Вы можете получить много компиляторов, чтобы проверить, согласны ли строки формата и аргументы: gcc/clang делают это через атрибуты, VC++ делает это через аннотации SAL. Если вы изменяете строку формата, такие проверки будут бессмысленными.) –

ответ

2

Вы не можете передавать вариационные аргументы в вариационную функцию. Вместо этого вы должны вызвать функцию, которая принимает аргумент va_list. Стандартная библиотека предоставляет варианты printf и scanf, которые принимают va_list; их имена имеют префикс v.

Ваш пример должен выглядеть следующим образом:

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

int printfln(const char *format, ...) 
{ 
    int result; 
    va_list args; 

    va_start(args, format); 
    result = vprintf(format, args); 
    printf("\n"); 
    va_end(args); 

    return result; 
} 

int main() 
{ 
    int result = printfln("Something \n %d", 9); 

    printf("(%d)\n", result); 

    return 0; 
} 

Есть несколько подводных камней, например, когда вы хотите вызвать две v... функцию для печати на экране и лог-файл: v... функция может исчерпать va_list, поэтому вы должны передавать свежие сообщения каждому вызову, если ваш код должен быть переносимым.

+0

Удивительный. он работает нормально. – Monk

+1

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

Смежные вопросы