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 13 Arrays
  gp 13.1 Arrays deklarieren
  gp 13.2 Initialisierung und Zugriff auf Arrays
    gp 13.2.1 Gültigkeitsbereich von Arrays
  gp 13.3 Arrays vergleichen
  gp 13.4 Anzahl der Elemente eines Arrays ermitteln
  gp 13.5 Übergabe von Arrays an Funktionen
  gp 13.6 Arrays aus Funktionen zurückgeben
  gp 13.7 Programmbeispiel zu den Arrays
  gp 13.8 Einlesen von Array-Werten
  gp 13.9 Mehrdimensionale Arrays
  gp 13.10 Mehrdimensionale Arrays initialisieren
    gp 13.10.1 Tic Tac Toe
    gp 13.10.2 Dreidimensionale Arrays
  gp 13.11 Übergabe von zwei- bzw. mehrdimensionalen Arrays an Funktionen
  gp 13.12 Arrays in Tabellenkalkulation einlesen (*.CSV–Dateien)
  gp 13.13 Strings/Zeichenketten (char Array)
    gp 13.13.1 Vom String zur Binärzahl
  gp 13.14 Einlesen von Strings
  gp 13.15 Standard-Bibliothek <string.h>
    gp 13.15.1 strcat() – Strings aneinander hängen
    gp 13.15.2 strchr() – ein Zeichen im String suchen
    gp 13.15.3 strcmp() – Strings vergleichen
    gp 13.15.4 strcpy() – einen String kopieren
    gp 13.15.5 strcspn() – einen Teilstring ermitteln
    gp 13.15.6 strlen() – Länge eines Strings ermitteln
    gp 13.15.7 strncat() – String mit n Zeichen aneinander hängen
    gp 13.15.8 strncmp() – n Zeichen von zwei Strings miteinander vergleichen
    gp 13.15.9 strncpy() – String mit n Zeichen kopieren
    gp 13.15.10 strpbrk() – Auftreten bestimmter Zeichen suchen
    gp 13.15.11 strrchr() – das letzte Auftreten eines bestimmten Zeichens im String suchen
    gp 13.15.12 strspn() – erstes Auftreten eines Zeichens, das nicht vorkommt
    gp 13.15.13 strstr() – String nach Auftreten eines Teilstrings durchsuchen
    gp 13.15.14 strtok() – String anhand bestimmter Zeichen zerlegen


Galileo Computing - Zum Seitenanfang

13.13 Strings/Zeichenketten (char Array)  downtop

Arrays vom Datentyp char werden Strings genannt. Ein String ist eine Kette von einzelnen char-Zeichen mit einer abschließenden 0 (nicht gleichzusetzen mit dem Zeichen '0'). char-Arrays sind typischerweise eindimensional.

Viele Programmierer, die auf die Programmiersprache C stoßen, sind verwundert, dass es keinen eigenen Datentyp für einen String gibt. Für ein char-Array gelten nicht nur die Einschränkungen der herkömmlichen Arrays, sondern es existiert auch das Problem der maximalen Länge von Arrays. Diese scheinbare Unflexibilität kann später, wenn sie effektiv eingesetzt wird, sehr ressourcensparend und schnell sein. Belassen Sie es aber erst einmal in den nächsten Kapiteln bei den etwas eingeschränkten char-Arrays.

Mit dem char-Array können Zeichenfolgen dargestellt und verarbeitet werden. Damit können Sie Benutzerschnittstellen und Textdateien verarbeiten und erstellen.

Eine Form der Stringkonstante wurde schon öfter in diesem Buch verwendet:

printf("Ich bin die Stringkonstante");

Generell lässt sich sagen: Alles, was sich zwischen zwei Hochkommata befindet, gilt als Stringkonstante.

Die Deklaration eines char-Arrays ist identisch mit der bisher bekannten Form der Array-Deklaration:

char string_array[100];

Im obigen Beispiel wird ein Array vom Datentyp char angelegt, das 100 einzelne Zeichen speichern kann. Dabei muss die Größe des Array-Feldes nicht mehr ausdrücklich mit angegeben werden:

const char hallo[] = { 'H', 'a', 'l', 'l', 'o', ' ',
                       'W', 'e', 'l', 't', '\n', '\0' };

Diese Schreibweise ist ebenfalls absolut korrekt, aber sehr umständlich. Daher können Sie ein char-Array auch anders, nämlich als einen String (dtsch. Zeichenkette), deklarieren:

const char hallo[] = { "Hallo Welt\n" };

Beide Variationen sind absolut gleichwertig. Hierzu die rechnerinterne Darstellung des Strings:

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 13.12   Der String »Hallo Welt« ist ein einfaches char-Array

Diese Zeichenkette benötigt zwölf Elemente (genauer: zwölf Bytes). Wenn Sie aber die Deklaration zu hallo[] genauer betrachten, werden Sie feststellen, dass hierfür eigentlich nur elf Zeichen erforderlich wären. Welche Bedeutung hat das zwölfte Zeichen? Bei einem String benötigen Sie immer ein Stringende-Zeichen, das das Ende eines Strings anzeigt. Das ist die Bedeutung des Zeichens '\0'. Das versehentliche Weglassen des Zeichens ist eine häufige Fehlerquelle, wenn beispielsweise Speicher für n Zeichen reserviert werden soll. Generell muss also bei einem Bedarf von n Zeichen immer für n+1 Zeichen Platz im Array reserviert werden. Hierzu ein kurzes Listing:

/* string1.c */
#include <stdio.h>
#include <stdlib.h>
char hello1[] = { "Hallo Welt\n" };
char output[] = { "Ich bin lesbar \0 Ich nicht mehr" };
char deznu[]  = { "Mich siehst du 0 Mich und die Null auch" };
int main(void) {
   printf("%s",hello1);
   printf("%s\n",output);
   printf("%s\n",deznu);
   return EXIT_SUCCESS;
}

Dieses Beispiel zeigt auch, wie Sie für die formatierte Ausgabe von Zeichenketten die Formatangabe %s verwenden können (s = String). Daher benötigt ein String ein Ende-Kennungszeichen. Bei dem String

char output[] = {"Ich bin lesbar \0 Ich nicht mehr"};

werden nur die Zeichen bis '\0' angezeigt. Der hintere Teil des Strings existiert nur im Arbeitsspeicher. Da zuvor das Zeichen für das Ende des Strings '\0' steht, wird dieser Teil nie am Bildschirm ausgegeben. Im nächsten Beispiel

char deznu[] = {"Mich siehst du 0 Mich und die Null auch"};

wird der ganze String ausgegeben, weil das Zeichen '0' nicht gleichzusetzen ist mit dem Zeichen '\0'.

Es wurde bereits erwähnt, dass es auch möglich ist, auf die einzelnen Zeichen eines Strings zuzugreifen. Wenn Sie einen String beispielsweise mithilfe einer for-Schleife auf seine Länge hin überprüfen wollen, prüfen Sie lediglich auf das Zeichen '\0'. Hier ein Beispiel dazu:

/* string2.c */
#include <stdio.h>
#include <stdlib.h>
char hello1[] = { "Hallo Welt" };
char output[] = { "Ich bin lesbar \0 Ich nicht mehr" };
char deznu[]  = { "Mich siehst du 0 Mich und die Null auch" };
int main(void) {
   int i;
   printf("%c", output[0]);      /* I */
   printf("%c'", hello1[9]);     /* t */
   printf("%c ", deznu[5]);      /* s */
   printf("%c", hello1[7]);      /* Gibt das Zeichen 'e' aus */
   printf("%c", output[12]);     /* a */
   printf("%c", deznu[5]);       /* s */
   deznu[1] = 'y';               /* aus 'i' wird 'y' */
   printf("%c\n", deznu[1]);     /* y */
   for(i=0; hello1[i] != '\0'; i++);
   printf("Länge von '%s' = %d Zeichen\n", hello1, i);
   for(i=0; output[i] != '\0'; i++);
   printf("Länge von '%s' = %d Zeichen\n", output, i);
   for(i=0; deznu[i] != '\0'; i++);
   printf("Länge von '%s' = %d Zeichen\n", deznu, i);
   return EXIT_SUCCESS;
}

Hier werden mit dem Feldindex einzelne Zeichen ausgegeben, genau wie bei den Arrays mit Zahlen. In diesem Fall wird der Text »It's easy« ausgegeben. Es ist natürlich auch möglich, den Inhalt zu verändern, etwa wie in der Zeile

deznu[1] = 'y';

geschehen. Anschließend wird mit

for(i=0; hello1[i] != '\0'; i++);

die Anzahl der Zeichen hochgezählt, die sich im String hello1[] ohne \0 befinden. Die Abbruchbedingung

hello1[i] != '\0';

ist so lange wahr, bis der Inhalt von hello1[i] == '\0' ist. In diesem Beispiel wäre das bei hello1[11]der Fall, da sich hier das Zeichen '\0' befindet. Beachten Sie hier, dass hinter der for-Schleife ein Semikolon steht. Es gibt in diesem Fall keinen Anweisungsblock zur for-Schleife. Hier wird die Variable i so lange hochgezählt, bis das Stringende-Zeichen '\0' erreicht wird. Gleiches gilt für die anderen beiden Strings.


Galileo Computing - Zum Seitenanfang

13.13.1 Vom String zur Binärzahl  toptop

Oben wurde behauptet, dass es in C keine Datentypen gibt, welche Zeichen darstellen können. Die Zeichen wurden mithilfe der ASCII-Code-Tabelle kodiert. Wie verhält sich dies jetzt mit der folgenden Stringkonstante?

char str[] = { "Hallo!\n" };

Wird dieser String in seine einzelnen Zeichen zerlegt, ergibt sich die Zeile:

/* gleichwertig zu "Hallo!\n" */
char str[] = { 'H', 'a', 'l', 'l', 'o', '!', '\n', '\0' };

Werden die einzelnen Zeichen jetzt anhand der ASCII-Code-Tabelle dekodiert, sieht der String schon anders aus:

char str[] = { 72, 97, 108, 108, 111, 33, 10, 0 };

Theoretisch könnten Sie den String auch so angeben und ausgeben lassen, wie das folgende Listing demonstriert:

/* string3.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   /* Hallo!\n ... */
   char str[] = { 72, 97, 108, 108, 111, 33, 10, 0 };
   printf("%s\n",str);
   return EXIT_SUCCESS;
}

Wenn Sie jetzt noch die einzelnen Werte in Binärzahlen umrechnen, können Sie den String aus der Sicht des Computers betrachten:

0100100001100001011011000110110001101111001000010000101000000000

Diese Erklärung soll Ihnen nur zeigen, dass Zeichenketten nicht magischer sind als ganz normale Zahlen-Arrays und in gewisser Hinsicht auch solche sind. Einen Beweis? Bitte sehr:

/* string4.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   int i;
   int str[] = { 72, 97, 108, 108, 111, 33, 10, 0 };
   for(i = 0; i < sizeof(str) / sizeof(int); i++)
      printf("%c", str[i]);
   return EXIT_SUCCESS;
}

Ein kleines Programm demonstriert im Folgenden den Umgang mit Strings. Das Programm durchläuft eine Zeichenkette und wandelt alle Stringfolgen "und" in Großbuchstaben um:

/* string5.c */
#include <stdio.h>
#include <stdlib.h>
char undbig[] = {
   "Hund und Katze sind nicht ohne "
   "Grund des Menschens bester Freund\n"
};
int main(void) {
  int i;
  for(i=0; undbig[i] != '\0'; i++) {
     if(undbig[i-1]==' '&& (undbig[i]=='u' ||undbig[i]=='U')) {
        if(undbig[i+1]=='n'&&undbig[i+2]=='d'&&undbig[i+3]==' '){
           undbig[i] = 'U';
           /* n zu Grossbuchstabe konvertieren (N) */
           undbig[i+1] -= 32;
           /* d zu Grossbuchstabe konvertieren  (D) */
           undbig[i+2] -= 32;
        }
      }
   }
   printf("%s", undbig);
   return EXIT_SUCCESS;
}

Zu Beginn des Programms sehen Sie, wie Sie eine Stringkonstante über mehrere Zeilen schreiben können.

char array[] = {
   "Eine Zeichenkette über"
   "2 Zeilen\n"
};
/* Alternative */
char array[] = {
   "Eine Zeichenkette über \
2 Zeilen"};

Beide Schreibweisen erfüllen den gleichen Zweck. Weiter mit der ersten for-Schleife des Programms:

for(i=0; undbig[i] != '\0'; i++)

Hier wird der String zeichenweise durchlaufen, bis das Stringende-Zeichen '\0' gefunden wird. Bei der nächsten Anweisung

if(undbig[i-1] == ' ' && (undbig[i]=='u' || undbig[i]=='U'))

wird überprüft, ob das Zeichen, bei dem sich der Feldindex gerade befindet, ein kleines 'u' oder großes 'U' und das Zeichen davor ein Whitespace-Zeichen (Leerzeichen) ist. Falls nicht, wird i in der for-Schleife um den Wert 1 inkrementiert. Wird ein 'u' oder 'U' gefunden, folgt die Überprüfung

if(undbig[i+1]=='n' && undbig[i+2]=='d' && undbig[i+3]==' ')

darauf hin, ob die nächsten beiden Zeichen 'n' und 'd' sind und ob sich dahinter ebenfalls ein Whitespace-Zeichen befindet. Falls dies ebenso zutrifft, wurde eine Zeichenfolge "und" gefunden. Dann werden die einzelnen Zeichen geändert:

undbig[i] = 'U';
undbig[i+1] -= 32;  /* 'n' – 32 */
undbig[i+2] -= 32;  /* 'd' – 32 */

Sehen Sie sich zum besseren Verständnis auch die ASCII-Tabelle im Anhang an. Sehen Sie nach, welche Dezimalwerte die Zeichen 'n' und 'd' haben. In Dezimalwerten würden die Subtraktionen der Werte so aussehen:

110–32=78 und 100–32=68

In der ASCII-Tabelle finden sich 'N' = 78 und 'D' = 68.

 << 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