web-dev-qa-db-fra.com

appeler printf en utilisant va_list

void TestPrint(char* format, ...)
{
    va_list argList;

    va_start(argList, format);
    printf(format, argList);
    va_end(argList);
}


int main()
{
    TestPrint("Test print %s %d\n", "string", 55);
    return 0;
}

J'ai besoin d'avoir:

Test print string 55

En fait, j'obtiens une sortie poubelle. Quel est le problème dans ce code?

45
Alex F

Utilisez plutôt vprintf() .

72

Au lieu de printf, je vous recommande d'essayer plutôt vprintf, qui a été créé dans ce but spécifique:

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

void errmsg( const char* format, ... )
{
  va_list arglist;

  printf( "Error: " );
  va_start( arglist, format );
  vprintf( format, arglist );
  va_end( arglist );
}

int main( void )
{
  errmsg( "%s %d %s", "Failed", 100, "times" );
  return EXIT_SUCCESS;
}

Source: http://www.qnx.com/developers/docs/6.5.0/index.jsp?topic=/com.qnx.doc.neutrino_lib_ref/v/vprintf.html

58
onteria_

Comme d'autres l'ont déjà souligné: dans ce cas, vous devez utiliser vprintf à la place.

Mais si vous voulez vraiment envelopper printf, ou si vous voulez envelopper une fonction qui n'a pas de v... version, vous pouvez le faire dans GCC en utilisant la version non standard __builtin_apply fonctionnalité:

int myfunction(char *fmt, ...)
{
    void *arg = __builtin_apply_args();
    void *ret = __builtin_apply((void*)printf, arg, 100);
    __builtin_return(ret);
}

Le dernier argument de __builtin_apply est le nombre max. taille totale des arguments en octets. Assurez-vous que vous utilisez ici une valeur suffisamment grande.

23
CliffordVienna

Ce n'est pas ainsi que vous utilisez printf(). Si vous souhaitez utiliser va_lists, Utilisez plutôt vprintf(). Regardez ici pour référence.

5
Constantinius