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

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1411-7
Pfeil 18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
Pfeil 18.1 Makros in <stdarg.h> – »va_list«, »va_arg«, »va_start« und »va_end«
Pfeil 18.2 Die Argumentliste am Anfang oder Ende kennzeichnen
Pfeil 18.3 »vprintf()«, »vsprintf()«, »vfsprintf()« und »vsnsprintf()«
Pfeil 18.4 Variadic Makros – __VA_ARGS__


Rheinwerk Computing - Zum Seitenanfang

18.3 »vprintf()«, »vsprintf()«, »vfsprintf()« und »vsnsprintf()« topZur vorigen Überschrift

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 sehen Sie die Syntax von vprintf():

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

int vprintf(const char * restrict format, va_list artPtr);

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

/* 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 * restrict f,
              const char * restrict puffer,
              va_list argPtr);

Diese Funktion ist gleichbedeutend mit der Funktion vprintf(), nur dass Sie dabei noch formatiert in einen 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 wie sprintf() funktioniert. Ihre Syntax lautet:

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

int vsprintf( const char * restrict puffer,
              const char * restrict format,
              va_list argPtr);

Damit kann eine variabel lange Argumentliste formatiert in einen String geschrieben werden. Hier sehen Sie ein kurzes Beispiel:

/* vsprintf.c */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/*  Bei Linux die 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;
}

Ab dem C99-Standard ist mit vsnprintf() auch die snprintf()-Alternative mit einer variablen Argumentliste neu hinzugekommen. Die Syntax dieser Funktion sieht so aus:

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


int vsnprintf( const char * restrict puffer,
               size_t n
               const char * restrict format,
               va_list argPtr );

Zwar wurden die Funktionen vprintf(), vfprintf(), vsprintf() und vsnsprintf() recht kurz abgehandelt, aber im Grunde arbeiten all diese Funktionen auf die gleiche Art und Weise wie ihre Gegenstücke printf(), fprintf(), sprintf() und snprintf(), nur dass der letzte Parameter immer ein Argumentzeiger vom Typ va_list ist, womit zusätzlich zur bereits vorhandenen Funktion der Gegenstücke auch noch optionale Argumente möglich sind. Um die Argumentliste verwenden zu können, muss diese immer zuerst mit va_start() initialisiert und am Ende mit va_end() beendet werden. va_arg() wird hier nicht benötigt, weil dieses Makro intern von den Funktionen verwendet wird.


Hinweis

Die Funktionen gibt es auch wieder für breite Zeichen. In diesem Fall wären dies vwprintf(), vfwprintf() und vswprintf().




Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: C/C++






 C/C++


Zum Katalog: Einstieg in C






 Einstieg in C


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
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.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de