printf, fprintf, sprintf, snprintf, wsprintf, vprintf, vfprintf, vsprintf, vwsprintf ou vdprintf Sous-routine

Objectif

Imprime la sortie formatée.

Bibliothèque

Bibliothèque C standard (libc.a) ou bibliothèque C standard avec doubles 128 bits (libc128.a)

Syntaxe

#include <stdio.h>

int printf (Format, [Value, ...])
const char *Format;

int fprintf (Stream, Format, [Value, ...])
FILE *Stream;
const char *Format;

int sprintf (String, Format, [Value, ...])
char *String;
const char *Format;

int snprintf (String, Number, Format, [Value, . . .])
char *String;
int Number;
const char *Format;
#include <stdarg.h>

int vprintf (Format, Value)
const char *Format;
va_list Value;

int vfprintf (Stream, Format, Value)
FILE *Stream;
const char *Format;
va_list Value;

int vsprintf (String, Format, Value)
char *String;
const char *Format;
va_list Value;

int vdprintf (fildes, Format, Value);
int fildes;
const char *Format;
va_list Value;
#include <wchar.h>

int vwsprintf (String, Format, Value)
wchar_t *String;
const char *Format;
va_list Value;

int wsprintf (String, Format, [Value, ...])
wchar_t *String;
const char *Format;

Descriptif

La sous-routine printf convertit, formate et écrit les valeurs du paramètre Valeur , sous le contrôle du paramètre Format , dans le flux de sortie standard. La sous-routine printf fournit des types de conversion pour gérer les points de code et les codes de caractères larges wchar_t .

La sous-routine fprintf convertit, formate et écrit les valeurs du paramètre Valeur , sous le contrôle du paramètre Format , dans le flux de sortie spécifié par le paramètre Flux . Cette sous-routine fournit des types de conversion pour gérer les points de code et les codes de caractères larges wchar_t .

La sous-routine sprintf convertit, formate et stocke les valeurs du paramètre Value , sous le contrôle du paramètre Format , en octets consécutifs, à partir de l'adresse spécifiée par le paramètre String . La sous-routine sprintf place un caractère null (\0) à la fin. Vous devez vous assurer que l'espace de stockage disponible est suffisant pour contenir la chaîne formatée. Cette sous-routine fournit des types de conversion pour gérer les points de code et les codes de caractères larges wchar_t .

La sous-routine snprintf convertit, formate et stocke les valeurs du paramètre Valeur , sous contrôle du paramètre Format , en octets consécutifs, à partir de l'adresse spécifiée par le paramètre Chaîne . La sous-routine snprintf place un caractère null (\0) à la fin. Vous devez vous assurer que l'espace de stockage disponible est suffisant pour contenir la chaîne formatée. Cette sous-routine fournit des types de conversion pour gérer les points de code et les codes de caractères larges wchar_t . La sous-routine snprintf est identique à la sous-routine sprintf avec l'ajout du paramètre Number , qui indique la taille de la mémoire tampon désignée par le paramètre String .

La sous-routine wsprintf convertit, formate et stocke les valeurs du paramètre Valeur , sous le contrôle du paramètre Format , en caractères wchar_t consécutifs à partir de l'adresse spécifiée par le paramètre Chaîne . La sous-routine wsprintf place un caractère null (\0) à la fin. Le processus appelant doit s'assurer que l'espace de stockage disponible est suffisant pour contenir la chaîne formatée. L'unité de largeur de zone est spécifiée en tant que nombre de caractères wchar_t . La sous-routine wsprintf est identique à la sous-routine printf , sauf que le paramètre String de la sous-routine wsprintf utilise une chaîne de codes de caractères larges wchar_t .

Toutes les sous-routines ci-dessus fonctionnent en appelant la sous-routine _doprnt à l'aide des fonctions d'argument de longueur variable des macros varargs .

Les sous-routines vdprintf, vprintf, vfprintf, vsprintfet vwsprintf formatent et écrivent des listes de paramètres de macros varargs . Ces sous-routines sont identiques aux sous-routines drpintf, printf, fprintf, sprintf, snprintfet wsprintf , respectivement, sauf qu'elles ne sont pas appelées avec un nombre variable de paramètres. Au lieu de cela, ils sont appelés avec un pointeur de liste de paramètres tel que défini par les macros varargs .

Remarque: A partir de IBM® AIX® 6 avec le niveau de technologie 7 et de IBM AIX 7 avec le niveau de technologie 1, la précision des routines de conversion à virgule flottante, de la famille de fonctions printf et scanf a été augmentée de 17 à 37 chiffres pour les valeurs doubles et longues.

Paramètres

Nombre
Indique le nombre d'octets d'une chaîne à copier ou à transformer.
Valeur
Indique 0 ou plusieurs arguments qui mappent directement aux objets dans le paramètre Format .
Flux
Indique le flux de sortie.
Chaîne
Indique l'adresse de début.
Format
Chaîne de caractères contenant deux types d'objet:
  • Caractères simples, qui sont copiés dans le flux de sortie.
  • Spécifications de conversion, chacune d'elles entraînant l'extraction de 0 ou de plusieurs éléments de la liste des paramètres Valeur . Dans le cas des sous-routines vprintf, vfprintf, vsprintfet vwsprintf , chaque spécification de conversion entraîne l'extraction de 0 ou de plusieurs éléments à partir des listes de paramètres de macros varargs .

    Si la liste de paramètres Valeur ne contient pas suffisamment d'éléments pour le paramètre Format , les résultats sont imprévisibles. S'il reste d'autres paramètres après le traitement de l'intégralité du paramètre Format , la sous-routine les ignore.

    Chaque spécification de conversion du paramètre Format comporte les éléments suivants:

  • % (signe de pourcentage).
  • 0 ou plusieurs options, qui modifient la signification de la spécification de conversion. Les caractères d'option et leur signification sont les suivants:
    '
    Formate les parties entières résultant des conversions décimales i, d, u, f, g et G avec des caractères de regroupement millièmes . Pour les autres conversions, le comportement n'est pas défini. Cette option utilise le caractère de regroupement non monétaire.
    -
    Justifie à gauche le résultat de la conversion dans la zone.
    +
    Commence le résultat d'une conversion signée par un signe + (signe plus) ou-(signe moins).
    caractère espace
    Préfixe un caractère espace au résultat si le premier caractère d'une conversion signée n'est pas un signe. Si le caractère espace et les caractères d'option + apparaissent, l'option de caractère espace est ignorée.
    #
    Convertit la valeur en une autre forme. Pour les conversions c, d, set u , l'option n'a aucun effet. Pour la conversion o , elle augmente la précision pour forcer le premier chiffre du résultat à être 0. Pour les conversions x et X , un résultat différent de zéro a un préfixe 0x ou 0X . Pour les conversions e, E, f, get G , le résultat contient toujours un séparateur décimal, même si aucun chiffre ne le suit. Pour les conversions g et G , les 0 de fin ne sont pas supprimés du résultat.
    0 %
    Remplit la largeur de la zone avec des 0 d'attaque (après toute indication de signe ou de base) pour les conversions d, i, o, u, x, X, e, E, f, get G ; la zone n'est pas remplie d'espace. Si les options 0 et - apparaissent toutes les deux, l'option 0 est ignorée. Pour les conversions d, i, o u, xet X , si une précision est spécifiée, l'option 0 est également ignorée. Si les options 0 et ' apparaissent toutes les deux, les caractères de regroupement sont insérés avant le remplissage de la zone. Pour les autres conversions, les résultats ne sont pas fiables.
    B
    Indique un caractère non opérationnel.
    N
    Indique un caractère non opérationnel.
    J
    Indique un caractère non opérationnel.
  • Chaîne facultative de chiffres décimaux qui spécifie la largeur minimale de la zone. Si la valeur convertie comporte moins de caractères que la largeur de la zone, la zone est remplie à gauche à la longueur spécifiée par la largeur de la zone. Si l'option - (justification à gauche) est spécifiée, la zone est remplie à droite.
  • Précision facultative. La précision est un . (point) suivi d'une chaîne de chiffres décimaux. Si aucune précision n'est spécifiée, la valeur par défaut est 0. La précision spécifie les limites suivantes:
    • Nombre minimal de chiffres devant apparaître pour les conversions d, i, o, u, xou X .
    • Nombre de chiffres devant figurer après le séparateur décimal pour les conversions e, Eet f .
    • Nombre maximal de chiffres significatifs pour les conversions g et G .
    • Nombre maximal d'octets à imprimer à partir d'une chaîne dans les conversions s et S .
    • Nombre maximal d'octets, convertis à partir du tableau wchar_t , à imprimer à partir des conversions S . Seuls les caractères complets sont imprimés.
  • Un spécificateur facultatif l (minuscule L), ll (minuscule LL), hou L indique l'un des éléments suivants:
    • Un h facultatif spécifiant qu'un spécificateur de conversion d, i, u, o, xou X ultérieur s'applique à un paramètre Valeur short int ou unsigned short int(le paramètre aura été promu en fonction des promotions intégrales, et sa valeur sera convertie en entier court ou entier court non signé avant l'impression).
    • Un h facultatif spécifiant qu'un spécificateur de conversion n ultérieur s'applique à un pointeur sur un paramètre short int .
    • Un l facultatif ( Len minuscules) spécifiant qu'un d, i, u, o, xou un spécificateur de conversion X ultérieur s'applique à un paramètre long int ou unsigned long int .
    • Un l facultatif (en minuscules L) spécifiant qu'un spécificateur de conversion n suivant s'applique à un pointeur sur un paramètre long int .
    • Un ll facultatif ( LLen minuscules) spécifiant qu'un spécificateur de conversion d, i, u, o, xou X suivant s'applique à un paramètre long long int ou unsigned long long int .
    • Un ll facultatif (en minuscules LL) spécifiant qu'un spécificateur de conversion n suivant s'applique à un pointeur sur un paramètre long long int .
    • Un L facultatif spécifiant qu'un spécificateur de conversion e, E, f, gou G suivant s'applique à un paramètre long double . S'il est lié à libc.a, long double est identique à double (64bits). S'il est lié à libc128.a et libc.a, long double est 128 bits.
  • Un spécificateur H, Dou DD facultatif indique l'une des conversions suivantes:
    • Un H facultatif spécifiant qu'un spécificateur de conversion e, E, f, F, gou G suivant s'applique à un paramètre _Decimal32 .
    • Un D facultatif spécifiant qu'un spécificateur de conversion e, E, f, F, gou G suivant s'applique à un paramètre _Decimal64 .
    • Une instruction DD facultative spécifiant qu'un spécificateur de conversion e, E, f, F, gou G suivant s'applique à un paramètre _Decimal128 .
  • Un spécificateur facultatif vl, lv, vh, hv ou v indique l'une des conversions de type de données vectorielles suivantes:
    • Un v facultatif spécifiant qu'un spécificateur de conversion e, E, f, g, G, aou A suivant s'applique à un paramètre vector float . Il consomme un argument et interprète les données comme une série de quatre composants à virgule flottante de 4 octets.
    • Un v facultatif spécifiant qu'un spécificateur de conversion c, d, i, u, o, xou X suivant s'applique à un paramètre vector signed char, vector unsigned charou vector bool char . Il consomme un argument et interprète les données comme une série de seize composants à 1 octet.
    • Un vl ou lv facultatif spécifiant qu'un spécificateur de conversion d, i, u, o, xou X suivant s'applique à un paramètre vector signed int, vector unsigned intou vector bool . Il consomme un argument et interprète les données comme une série de quatre composants entiers de 4 octets.
    • Un vh ou hv facultatif spécifiant qu'un spécificateur de conversion d, i, u, o, xou X suivant s'applique à un paramètre vector signed short ou vector unsigned short . Il consomme un argument et interprète les données comme une série de huit composants entiers de 2 octets.
    • Pour l'un des spécificateurs précédents, un caractère de séparation facultatif peut être indiqué immédiatement avant le spécificateur de taille de vecteur. Si aucun séparateur n'est spécifié, le séparateur par défaut est un espace sauf si la conversion est c, auquel cas le séparateur par défaut est null. Les séparateurs facultatifs pris en charge sont , (virgule), ; (point-virgule), : (deux-points) et _ (trait de soulignement).
  • Les caractères suivants indiquent le type de conversion à appliquer:
    %
    N'effectue aucune conversion. Imprime (%).
    d ou i
    Accepte un paramètre Valeur spécifiant un entier et le convertit en notation décimale signée. La précision indique le nombre minimal de chiffres à afficher. Si la valeur convertie peut être représentée en moins de chiffres, elle est développée avec des 0 de début. La précision par défaut est 1. Le résultat de la conversion d'une valeur de 0 avec une précision de 0 est une chaîne nulle. La spécification d'une largeur de zone avec un 0 comme caractère de début entraîne le remplissage de la valeur de largeur de zone avec des 0 de début.
    U
    Accepte un paramètre Valeur spécifiant un entier non signé et le convertit en notation décimale non signée. La précision indique le nombre minimal de chiffres à afficher. Si la valeur convertie peut être représentée en moins de chiffres, elle est développée avec des 0 de début. La précision par défaut est 1. Le résultat de la conversion d'une valeur de 0 avec une précision de 0 est une chaîne nulle. La spécification d'une largeur de zone avec un 0 comme caractère de début entraîne le remplissage de la valeur de largeur de zone avec des 0 de début.
    o
    Accepte un paramètre Valeur spécifiant un entier non signé et le convertit en notation octale non signée. La précision indique le nombre minimal de chiffres à afficher. Si la valeur convertie peut être représentée en moins de chiffres, elle est développée avec des 0 de début. La précision par défaut est 1. Le résultat de la conversion d'une valeur de 0 avec une précision de 0 est une chaîne nulle. La spécification d'une largeur de zone avec un 0 comme caractère de début entraîne le remplissage de la valeur de largeur de zone avec des 0 de début. Une valeur octale pour la largeur de zone n'est pas implicite.
    x ou X
    Accepte un paramètre Valeur spécifiant un entier non signé et le convertit en notation hexadécimale non signée. Les lettres abcdef sont utilisées pour la conversion x et les lettres ABCDEF sont utilisées pour la conversion X . La précision indique le nombre minimal de chiffres à afficher. Si la valeur convertie peut être représentée en moins de chiffres, elle est développée avec des 0 de début. La précision par défaut est 1. Le résultat de la conversion d'une valeur de 0 avec une précision de 0 est une chaîne nulle. La spécification d'une largeur de zone avec un 0 comme caractère de début entraîne le remplissage de la valeur de largeur de zone avec des 0 de début.
    F
    Accepte un paramètre Valeur spécifiant un double et le convertit en notation décimale au format [-]ddd.ddd. Le nombre de chiffres après le séparateur décimal est égal à la spécification de précision. Si aucune précision n'est indiquée, six chiffres sont générés. Si la précision est 0, aucun séparateur décimal n'apparaît.
    e ou E
    Accepte un paramètre Valeur spécifiant un double et le convertit au format exponentiel [-]d.ddde+/-jj. Il existe un chiffre avant le séparateur décimal et le nombre de chiffres après le séparateur décimal est égal à la spécification de précision. La spécification de précision peut être comprise entre 0 et 17 chiffres. Si aucune précision n'est indiquée, six chiffres sont générés. Si la précision est 0, aucun séparateur décimal n'apparaît. Le caractère de conversion E génère un nombre avec E au lieu de e avant l'exposant. L'exposant contient toujours au moins deux chiffres.
    g ou G
    Accepte un paramètre Valeur spécifiant un double et le convertit dans le style des caractères de conversion e, Eou f , avec la précision indiquant le nombre de chiffres significatifs. Les 0 de fin sont supprimés du résultat. Un séparateur décimal n'apparaît que s'il est suivi d'un chiffre. Le style utilisé dépend de la valeur convertie. Le style e (E, si l'indicateur utilisé est G ) ne résulte que si l'exposant résultant de la conversion est inférieur à -4, ou s'il est supérieur ou égal à la précision. Si une précision explicite est 0, elle est prise comme 1.
    c
    Accepte et imprime un paramètre Valeur spécifiant un entier converti en type de données char non signé.
    C
    Accepte et imprime un paramètre Valeur spécifiant un code de caractère large wchar_t . Le code de caractère large wchar_t spécifié par le paramètre Valeur est converti en un tableau d'octets représentant un caractère et ce caractère est écrit ; le paramètre Valeur est écrit sans conversion lors de l'utilisation de la sous-routine wsprintf .
    s
    Accepte un paramètre Valeur en tant que chaîne (pointeur de caractères) et les caractères de la chaîne sont imprimés jusqu'à ce qu'un caractère null (\0) soit rencontré ou que le nombre d'octets indiqué par la précision soit atteint. Si aucune précision n'est indiquée, tous les octets jusqu'au premier caractère nul sont imprimés. Si le pointeur de chaîne spécifié par le paramètre Valeur a une valeur nulle, les résultats ne sont pas fiables.
    S
    Accepte un paramètre Valeur correspondant comme pointeur vers une chaîne wchar_t . Les caractères de la chaîne sont imprimés (sans conversion) jusqu'à ce qu'un caractère nul (\0) soit détecté ou que le nombre de caractères larges indiqué par la précision soit atteint. Si aucune précision n'est indiquée, tous les caractères jusqu'au premier caractère nul sont imprimés. Si le pointeur de chaîne spécifié par le paramètre Valeur a la valeur null, les résultats ne sont pas fiables.
    p
    Accepte un pointeur vide. La valeur du pointeur est convertie en une séquence de caractères imprimables, identique à une valeur hexadécimale non signée (x).
    n
    Accepte un pointeur vers un entier dans lequel est écrit le nombre de caractères (codes de caractères larges dans le cas de la sous-routine wsprintf ) écrits dans le flux de sortie par cet appel. Aucun argument n'est converti.
 

La largeur ou la précision d'une zone peut être indiquée par un astérisque (*) au lieu d'une chaîne de chiffres. Dans ce cas, un paramètre Valeur entier fournit la largeur ou la précision de la zone. Le paramètre Valeur converti pour la sortie n'est pas extrait tant que la lettre de conversion n'est pas atteinte. Par conséquent, les paramètres spécifiant la largeur ou la précision de la zone doivent apparaître avant la valeur (le cas échéant) à convertir.

Si le résultat d'une conversion est plus large que la largeur de la zone, la zone est développée pour contenir le résultat converti et aucune troncature n'est effectuée. Toutefois, une faible largeur de champ ou une faible précision peut entraîner une troncature à droite.

La sous-routine printf, fprintf, sprintf, snprintf, wsprintf, vprintf, vfprintf, vsprintfou vwsprintf permet l'insertion d'un caractère de base dépendant du langage dans la chaîne de sortie. Le caractère de base est défini par les données spécifiques à la langue dans la catégorie LC_NUMERIC de l'environnement local du programme. Dans l'environnement local C, ou dans un environnement local où le caractère de base n'est pas défini, le caractère de base par défaut est a. (point).

Une fois que l'exécution de l'une de ces sous-routines a abouti et avant la prochaine exécution réussie d'un appel à la sous-routine fclose ou fflush sur le même flux ou à la sous-routine exit ou abort , lest_ctimeetst_mtimeLes zones du fichier sont marquées pour la mise à jour.

Les spécificateurs de conversion e, E, f, get G représentent les valeurs à virgule flottante spéciales comme suit:

Article Descriptif
Silencieux NaN +NaNQ ou -NaNQ
Signalisation NaN +NaNS ou -NaNS
+/-INF + INF ou -INF
+/-0 +0 ou -0

La représentation du signe + (plus) varie selon que l'option de formatage + ou espace-caractère est spécifiée.

Ces sous-routines peuvent traiter une chaîne de format qui permet au système de traiter les éléments de la liste de paramètres dans l'ordre des variables. Dans ce cas, le caractère de conversion normal% (signe pourcentage) est remplacé par %chiffre$, où chiffre est un nombre décimal compris entre 1 et la valeur NL_ARGMAX . La conversion est ensuite appliquée à l'argument spécifié, plutôt qu'à l'argument non utilisé suivant. Cette fonction permet de définir des chaînes de format dans un ordre adapté à des langues spécifiques. Lorsque l'ordre des variables est utilisé, la spécification * (astérisque) pour la précision de la largeur de champ est remplacée par %chiffre$. Si vous utilisez la fonction de classement des variables, vous devez la spécifier pour toutes les conversions.

Les critères suivants s'appliquent:

  • Le format transmis aux extensions NLS peut contenir le format de la conversion ou le nombre d'arguments explicites ou implicites. Toutefois, ces formats ne peuvent pas être mélangés dans une chaîne de format unique, à l'exception de %% (signe de pourcentage double).
  • La valeur n ne doit pas comporter de zéros non significatifs.
  • Si %n$ est utilisé, %1$ à %n- 1$ inclus doit être utilisé.
  • La valeur n dans %n$ est comprise entre 1 et la valeur NL_ARGMAX , incluse. Pour plus d'informations sur la valeur NL_ARGMAX , voir le fichier limits.h .
  • Les arguments numérotés de la liste d'arguments peuvent être référencés autant de fois que nécessaire.
  • La spécification * (astérisque) pour la largeur ou la précision de la zone n'est pas autorisée avec le format %n$ de l'ordre des variables ; à la place, le format *m$ est utilisé.

Valeurs renvoyées

Une fois l'opération terminée, les sous-routines printf, fprintf, vprintfet vfprintf renvoient le nombre d'octets transmis (à l'exclusion du caractère null [ \0 ] dans le cas des sous-routines sprintfet vsprintf ). Si une erreur est détectée, une valeur négative est générée.

Une fois l'opération terminée, la sous-routine snprintf renvoie le nombre d'octets écrits dans le paramètre String (à l'exclusion de l'octet null de fin). Si les caractères de sortie sont supprimés car la longueur de la sortie dépasse le paramètre Nombre , la sous-routine snprintf renvoie le nombre d'octets qui auraient été écrits dans le paramètre Chaîne si le paramètre Nombre avait été suffisamment grand (à l'exclusion de l'octet NULL de fin).

Une fois l'opération terminée, les sous-routines wsprintf et vwsprintf renvoient le nombre de caractères larges transmis (à l'exclusion du caractère large null [ \0 ]). Si une erreur est détectée, une valeur négative est générée.

Codes d'erreur

La sous-routine printf, fprintf, sprintf, snprintfou wsprintf échoue si le fichier spécifié par le paramètre Stream n'est pas mis en mémoire tampon ou si la mémoire tampon doit être vidée et qu'une ou plusieurs des conditions suivantes sont remplies:

Article Descriptif
FEAGA L'indicateur O_NONBLOCK ou O_NDELAY est défini pour le descripteur de fichier sous-jacent au fichier spécifié par le paramètre Stream ou String et le processus est retardé dans l'opération d'écriture.
EBADF Le descripteur de fichier sous-jacent au fichier spécifié par le paramètre Stream ou String n'est pas un descripteur de fichier valide ouvert en écriture.
EFBIG Une tentative d'écriture a été effectuée dans un fichier qui dépasse la limite de taille de fichier de ce processus ou la taille de fichier maximale. Pour plus d'informations, reportez-vous à la sous-routine ulimit .
EINTR L'opération d'écriture s'est arrêtée en raison de la réception d'un signal et aucune donnée n'a été transférée ou un transfert partiel n'a pas été signalé.
Remarque: En fonction de la routine de bibliothèque à laquelle l'application est liée, cette sous-routine peut renvoyer EINTR. Reportez-vous à la sous-routine signal concernant sa_restart.
Article Descriptif
EIO Le processus est membre d'un groupe de processus d'arrière-plan qui tente d'effectuer une écriture sur son terminal de contrôle, l'indicateur TOSTOP est défini, le processus n'ignore ni ne bloque le signal SIGTTOU et le groupe de processus du processus n'a pas de processus parent.
ENOSPC Il ne reste plus d'espace disponible sur l'unité qui contient le fichier.
EOVERFLOW

En mode UNIX03 , la sous-routine snprintf ou vsnprintf échoue si la valeur du paramètre Number est supérieure à la valeur de INT_MAX.

Remarque: Le comportement UNIX03 est activé si la valeur de la variable d'environnement XPG_SUS_ENV est définie sur ON.
EPIPE Une tentative d'écriture a été effectuée sur un canal de communication ou un premier entré-premier sorti (FIFO) qui n'est pas ouvert à la lecture par un processus. Un signal SIGPIPE est envoyé au processus.

La sous-routine printf, fprintf, sprintf, snprintfou wsprintf peut échouer si une ou plusieurs des conditions suivantes sont remplies:

Article Descriptif
EILSEQ Une séquence de caractères non valide a été détectée.
EINVAL Le paramètre Format a reçu des arguments insuffisants.
ENOMEM L'espace de stockage disponible est insuffisant.
ENXIO Une demande a été émise pour une unité inexistante ou la demande était en dehors des fonctions de l'unité.

Exemples

L'exemple suivant montre comment la sous-routine vfprintf peut être utilisée pour écrire une routine d'erreur:

#include <stdio.h>
#include <stdarg.h>
/* The error routine should be called with the
     syntax:       */
/* error(routine_name, Format
     [, value, . . . ]); */
/*VARARGS0*/
void error(char *fmt, . . .);
/* **  Note that the function name and
     Format arguments cannot be **
     separately declared because of the **
     definition of varargs.  */  {
   va_list args;

   va_start(args, fmt);
   /*
   ** Display the name of the function
      that called the error routine   */
   fprintf(stderr, "ERROR in %s: ",
      va_arg(args, char *));   /*
   ** Display the remainder of the message
   */
   fmt = va_arg(args, char *);
   vfprintf(fmt, args);
   va_end(args);
    abort();  }