Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch für Linux, Unix und Windows
– 2., aktualisierte und erweiterte Auflage 2006
Buch: C von A bis Z

C von A bis Z
1.116 S., mit CD, Referenzkarte, 39,90 Euro
Galileo Computing
ISBN 3-89842-643-2
gp Kapitel 20 Arbeiten mit variablen langen Argumentlisten – <stdarg.h>
  gp 20.1 Makros in <stdarg.h> – va_list, va_arg, va_start und va_end
  gp 20.2 Argumentliste am Anfang oder Ende kennzeichnen
  gp 20.3 vprintf, vsprintf und vfsprintf


Galileo Computing - Zum Seitenanfang

20.3 vprintf, vsprintf und vfsprintf  toptop

Mit dem Makro va_arg werden die variablen Parameter einzeln verarbeitet. Mit den beiden Funktionen vprintf() und vfprintf() kann die ganze Liste in einem Stück übernommen werden. Dazu wird der Makroname va_arg nicht mehr benötigt. Hier die Syntax von vprintf():

int vprintf(char *format, va_list name);

Jetzt soll hiermit die Funktion printf() nachgebildet werden. Der Code:

/* my_printf.c */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
static void myprintf(char *string, ...) {
   va_list argzeiger;
   va_start(argzeiger,string);
   vprintf(string,argzeiger);
   va_end(argzeiger);
}
int main(void) {
   char hallo[] = "Hallo vprintf\n";
   myprintf("Hier ein Beispiel von vprintf....");
   myprintf("\n");
   myprintf("%d * %d = %d\n",10,10,10*10);
   myprintf("%s",hallo);
   return EXIT_SUCCESS;
}

Der einzige Unterschied zu den vorigen Beispielen ist, dass hier anstatt va_arg() die Funktion vprintf() benutzt wird. Diese Funktion übernimmt den ganzen String in einem Stück. Natürlich macht dieses Programm wenig Sinn. vprintf() eignet sich sehr gut, um eigene Fehlermeldungsroutinen zu schreiben. Ein Beispiel:

/* error_handling.c */
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#define MAXWERT 8192
enum{ WARN, ERROR, EXIT, MISC };
/* Stringtabelle mit Fehlerausgaben */
const char *error[] = {
   "Fehlerhafte Eingabe\n",
   "Maximaler Wertebereich ueberschritten\n",
   "Nagativer Wert wurde eingegeben\n"
};
void fehler(int kennung, const char *format, ...) {
   va_list vargzeiger;
   va_start(vargzeiger,format);
   switch(kennung) {
      case 0  : printf("\nAchtung: ");
                vprintf(format,vargzeiger);
                break;
      case 1  : printf("\nFehler : ");
                vprintf(format,vargzeiger);
                break;
      case 2  : printf("\nProgrammabbruch : ");
                vprintf(format,vargzeiger);
                exit(EXIT_FAILURE);
      case 3  : vprintf(format,vargzeiger);
                break;
      default : printf("\nFalscher Funktionsaufruf\n");
   }
   va_end(vargzeiger);
}
int main(void) {
   int zahl, ret;
   printf("Eine Zahl zwischen 0–8192: ");
   ret=scanf("%d",&zahl);
   /* Fehlerhafte Eingabe vorgenommen */
   if(ret == 0)
      fehler(EXIT, error[0]);
   /* Zahl größer als Maximalwert */
   else if(zahl > MAXWERT)
      fehler(WARN, error[1]);
   /* Negative Zahl */
   else if(zahl < 0)
      fehler(ERROR, error[2]);
   /* Alles in bester Ordnung */
   else
      fehler(MISC, "Eingabe ist in Ordnung\n");
   return EXIT_SUCCESS;
}

Damit kann jederzeit mit dem Funktionsaufruf

fehler(kennungsnummer,"Fehler – Unbekannter Fehler");

eine bestimmte Fehlermeldung auf dem Bildschirm ausgegeben werden. Je nachdem, welche Kennungsnummer an die Funktion fehler() übergeben wurde. In diesem Beispiel wurden die Fehlernummern in enum-Variablen gekleidet und die entsprechende Fehlerausgabe in eine Stringtabelle.

Das dateiorientierte Gegenstück zu vprintf() ist die Funktion vfprintf() mit folgender Syntax:

#include <stdio.h>
#include <stdarg.h>
int vfprintf(FILE *f, const char *puffer, va_list arg);

Diese Funktion ist gleichbedeutend mit der Funktion vprintf(), nur dass Sie dabei noch formatiert in einem Stream oder aber auch auf die Standardausgabe schreiben können mit:

vfprintf(stdout, format, vargzeiger);
// gleichwertig zu ...
vprintf(format, vargzeiger);

Zudem existiert noch die Funktion vsprintf(), die ähnlich funktioniert wie sprintf(). Die Syntax:

#include <stdio.h>
#include <stdarg.h>
int vsprintf(const char *puffer,const char *format,
             va_list argzeiger);

Damit kann eine variabel lange Argumentliste formatiert in einen String geschrieben werden. Ein kurzes Beispiel:

/* vsprintf.c */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/*  Bei Linux Bibliothek math.h extra hinzulinken (-lm)
 *  gcc -o programm programm.c -lm
 */
#include <math.h>
static void float2string(char *string, char *dezimal, ...) {
   va_list argzeiger;
   va_start(argzeiger,dezimal);
   vsprintf(string,dezimal,argzeiger);
   va_end(argzeiger);
}
int main(void) {
   char string[100];
   float zahl = 20.0;
   float2string(&string[0],"string-> %.6f <-string",sqrt(zahl));
   printf("%s\n",string);
   return EXIT_SUCCESS;
}
 << zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z
C von A bis Z
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-Programmierung


Zum Katalog: C/C++






 C/C++


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Reguläre Ausdrücke






 Reguläre Ausdrücke


Zum Katalog: Linux






 Linux


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de