2011-01-24 3 views
14

Как обучающий опыт я портирование некоторых вещей из Windows на MacOS и наткнулся на что-то вроде этого:Замена для MS _vscprintf на MacOS/Linux?

void SomeClass::someFunction(const char* format, va_list args) 
{ 
    int size = _vscprintf(format, args); // length after formatting 
    std::string s; 
    s.resize(size); 
    vsprintf(&s[0]); 
    ... 
} 

Теперь, как _vscprintf является Microsoft специфичен и я не нашел ничего похожего на Linux я думал, спросите здесь.

Предположим также, что этот код имеет некоторый критический путь и не должен иметь дополнительных накладных расходов на распределение кучи или такого.

Какая рекомендуемая замена для _vscprintf на MacOS/Linux?

Спасибо!

+1

возможно дубликат [\ _vscprintf эквивалент на Android?] (Http://stackoverflow.com/questions/7825648/vscprintf-equivalent-on-android) – ismail

+0

Там не может быть прямой заменой для функция _vscprintf; но если вы используете его вместе с 'vsprintf' (как в примере' someFunction'), вы можете вместо этого использовать функцию 'asprintf' (если она доступна в вашей системе). – oliver

ответ

13

Вместо этого вы можете использовать vsnprintf;

int _vscprintf (const char * format, va_list pargs) { 
     int retval; 
     va_list argcopy; 
     va_copy(argcopy, pargs); 
     retval = vsnprintf(NULL, 0, format, argcopy); 
     va_end(argcopy); 
     return retval; 
    } 

Благодаря @dbasic для более полного решения и @ j-a для исправления очевидных ошибок.

+0

То же. Не только это, но и разумное ожидание от этого - авария – jheriko

+0

, так что если этот ответ не годится, что тогда? –

+0

-1, так как это невозможно удалить i downvote it – Janosch

13

Предыдущее решение в порядке, но есть две ошибки:

  1. Функция va_copy имеет один параметр вместо двух параметров.
  2. В вызове функции vsnprintf не используется переменная argcopy; он генерирует повреждение в стеке, если вы снова вызываете vsnprintf.
int _vscprintf (const char * format, va_list pargs) 
{ 
    int retval; 
    va_list argcopy; 
    va_copy(argcopy, pargs); 
    retval = vsnprintf(NULL, 0, format, argcopy); 
    va_end(argcopy); 
    return retval; 
} 
+0

Вы не должны помещать в отступы ничего, кроме кода или комментариев. –

+1

Обычно, когда вы передаете 'va_list' функции, предполагается, что она будет« потребляться »вызываемой функцией.Код 'va_copy()' обычно находится в 'SomeClass :: someFunction()' в вопросе, а не в библиотечной функции. Единственный безопасный способ вызвать библиотечную функцию - это копия 'va_list'. Я ничего не вижу на страницах руководства MS (http://msdn.microsoft.com/en-us/library/w05tbk72%28v=vs.110%29.aspx и http://msdn.microsoft.com/en-us /library/t32cf9tb%28v=vs.110%29.aspx), чтобы указать иное. –

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