Buchgenerator (deaktivieren)

C-Programmierung: Zeichenkettenfunktionen

Aus Wikibooks

Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

[Bearbeiten] Zeichenkettenfunktionen

Für die Bearbeitung von Strings stellt C eine Reihe von Bibliotheksfunktionen zu Verfügung:

[Bearbeiten] strcpy

char* strcpy(char* Ziel, const char* Quelle)

Kopiert einen String in einen anderen (Quelle nach Ziel) und liefert Zeiger auf Ziel als Funktionswert. Bitte beachten Sie, dass eine Anweisung text2 = text1 für ein Array nicht möglich ist. Für eine Kopie eines Strings in einen anderen ist immer die Anweisung strcpy nötig, da eine Zeichenkette immer Zeichenweise kopiert werden muss.

Beispiel:

  1. #include <stdio.h>
    
  2. #include <string.h>
    
  3.  
    
  4. int main(void)
    
  5. {
    
  6.   char text[20];
    
  7.  
    
  8.   strcpy(text, "Hallo!");
    
  9.   printf("%s\n", text);
    
  10.   strcpy(text, "Ja Du!");
    
  11.   printf("%s\n", text);
    
  12.   return 0;
    
  13. }
    

Nach dem Übersetzen und Ausführen erhält man die folgende Ausgabe:

Hallo!
Ja Du!

[Bearbeiten] strcmp

int strcmp(char* s1, char* s2);

Diese Stringfunktion ist für den Vergleich von zwei Strings zu verwenden. Die Strings werden Zeichen für Zeichen durchgegangen und ihre ASCII-Codes verglichen. Wenn die beiden Zeichenketten identisch sind, gibt die Funktion den Wert 0 zurück. Sind die Strings unterschiedlich, gibt die Funktion entweder einen Rückgabewert größer oder kleiner als 0 zurück: Ein Rückgabewert >0 (<0) bedeutet, der erste ungleiche Buchstabe in s1 hat einen größeren (kleineren) ASCII-Code als der in s2.

Beispiel:

  1. #include <stdio.h>
    
  2. #include <string.h>
    
  3.  
    
  4. int main()
    
  5. {
    
  6.   const char string1[] = "Hello";
    
  7.   const char string2[] = "World";
    
  8.   const char string3[] = "Hello";
    
  9.  
    
  10.   if (strcmp(string1,string2) == 0)
    
  11.   {
    
  12.     printf("Die beiden Zeichenketten %s und %s sind identisch.\n",string1,string2);
    
  13.   }
    
  14.   else
    
  15.   {
    
  16.     printf("Die beiden Zeichenketten %s und %s sind unterschiedlich.\n",string1,string2);
    
  17.   }
    
  18.  
    
  19.   if (strcmp(string1,string3) == 0)
    
  20.   {
    
  21.     printf("Die beiden Zeichenketten %s und %s sind identisch.\n",string1,string3);
    
  22.   }
    
  23.   else
    
  24.   {
    
  25.     printf("Die beiden Zeichenketten %s und %s sind unterschiedlich.\n",string1,string3);
    
  26.   }	
    
  27.  
    
  28.   return 0;
    
  29. }
    

Nach dem Ausführen erhält man folgende Ausgabe:

Die beiden Zeichenketten Hello und World sind unterschiedlich.
Die beiden Zeichenketten Hello und Hello sind identisch.


[Bearbeiten] strcat

char* strcat(char* s1, const char* s2)

Verbindet zwei Zeichenketten miteinander. Natürlich wird das Stringende-Zeichen \0 von s1 überschrieben. Voraussetzung ist, dass s2 in s1 Platz hat.

Beispiel:

  1. #include <stdio.h>
    
  2. #include <string.h>
    
  3.  
    
  4. int main(void)
    
  5. {
    
  6.   char text[20];
    
  7.   strcpy(text, "Hallo!");
    
  8.   printf("%s\n", text);
    
  9.   strcat(text, "Ja du!");
    
  10.   printf("%s\n", text);
    
  11.   return 0;
    
  12. }
    

Nach dem Übersetzen und Ausführen erhält man die folgende Ausgabe:

Hallo!
Hallo!Ja du!

Wie Sie sehen wird der String in Zeile 9 diesmal nicht überschrieben, sondern am Ende angehängt.

[Bearbeiten] strncat

Eine sichere Variante ist strncat:

char* strncat(char* s1, const char* s2,size_t n)

Es werden nur n Elemente angehängt. Damit wird sichergestellt, dass nicht in einen undefinierten Speicherbereich geschrieben wird.



[Bearbeiten] strtok

char *strtok( char *s1, const char *s2 )

Die Funktion strtok zerlegt einen String(s1) in einzelne Teilstrings anhand von sogenannten Token. Der String wird dabei durch ein Trennzeichen(s2) getrennt.
"s2" kann mehrere Trennzeichen enthalten, z.B. s2=" ,\n." (d.h. Trennung bei Space, Komma, New-Line, Punkt).

Beispiel:

Text: "Das ist ein Beispiel!"
Trennzeichen: " " //Leerzeichen

Token1: "Das"
Token2: "ist"
Token3: "ein"
Token4: "Beispiel!"


Der Code zu diesem Beispiel würde folgendermaßen aussehen:

  1. #include <stdio.h>
    
  2. #include <string.h>
    
  3.  
    
  4. int main(void){
    
  5. 	char text[] = "Das ist ein Beispiel!";
    
  6. 	char trennzeichen[] = " ";
    
  7. 	char *wort;
    
  8. 	int i=1;
    
  9. 	wort = strtok(text, trennzeichen);
    
  10. 	while(wort != NULL) {
    
  11. 	    printf("Token %d: %s\n", i++, wort);
    
  12. 	    wort = strtok(NULL, trennzeichen); 
    
  13. //Jeder Aufruf gibt das Token zurück. Das Trennzeichen wird mit '\0' überschrieben. 
    
  14. //Die Schleife läuft durch bis strtok() den NULL-Zeiger zurückliefert.
    
  15. 	}
    
  16. 	return 0;
    
  17. }
    

[Bearbeiten] strcspn

int strcspn (const *s1, const *s2)

strcspn() ist eine Funktion der Standardbibliothek string.h die, je nach Compiler, in jedes C-Programm implementiert werden kann. strcspn() dient dazu, die Stelle eines Zeichens zu ermitteln, an der es zuerst in einem String vorkommt.

Sobald ein Zeichen aus s2 in s1 gefunden wird, wird der Wert der Position an der es gefunden wurde, zurückgegeben.

Beispiel:

  1. /*Beispiel zu strcspn()*/
    
  2.  
    
  3. #include <stdio.h>
    
  4. #include <string.h>
    
  5.  
    
  6. int main(void){
    
  7. 	char s1[]="Das ist ein Text", s2[]="tbc";
    
  8. 	int position=0;
    
  9. 	position=strcspn(s1,s2);
    
  10. 	printf("Das erste Zeichen von %s tritt an der Stelle %i auf.\n", s2, position+1);
    
  11. 	return 0;
    
  12. }
    


Das erste Zeichen von tbc tritt an der Stelle 7 auf.


Achtung: es wird der Index im Char-Array ermittelt.

[Bearbeiten] strpbrk

Die strpbrk()-Funktion ist ähnlich wie die strcspn()-Funktion, nur dass bei dieser Funktion nicht die Länge eines Teilstrings ermittelt wird, sondern das erste Auftreten eines Zeichens in einem String, welches im Suchstring enthalten ist.

Die Syntax lautet:

char *strpbrk( const char *string1, const char *string2);

Ein Beispiel:

  1. #include <stdio.h>
    
  2. #include <string.h>
    
  3.  
    
  4. int main()
    
  5. {
    
  6.    char str1[]="Das ist ein Teststring";
    
  7.    char str2[]="i";
    
  8.    printf("%s\n", strpbrk(str1, str2));
    
  9.    return 0;
    
  10. }
    

Rückgegeben wird:

ist ein Teststring

Man sieht an diesem Beispiel, dass ab dem Suchzeichen (str2) abgeschnitten wird.

[Bearbeiten] strrchr

char *strrchr(const char *s, int ch)

strrchr() ist eine Stringfunktion, die das letzte Auftreten eines Zeichens in einer Zeichenkette sucht.


Im folgenden Beispiel wird eine Zeichenkette mit fgets eingelesen. fgets hängt am Ende ein New-Line-Zeichen an (\n). Wir suchen mit einem Zeiger nach diesem Zeichen und ersetzen es durch ein '\0'-Zeichen.


  1. #include <stdio.h>
    
  2. #include <string.h>
    
  3.  
    
  4. int main()
    
  5. {
    
  6.    char string[20];
    
  7.    char *ptr;
    
  8.  
    
  9.    printf("Eingabe machen:\n");
    
  10.    fgets(string, 20 , stdin);
    
  11.    /* man setzt den zeiger auf das New-Line-Zeichen */
    
  12.    ptr = strrchr(string, '\n');
    
  13.    /* \n-Zeichen mit \0 überschreiben */
    
  14.    *ptr = '\0';
    
  15.    printf("%s\n",string);
    
  16.    return 0;
    
  17. }
    

[Bearbeiten] strcmp

int strcmp(const char *x, const char *y);

Für das Vergleichen zweier Strings wird die Funktion strcmp() verwendet. Sind beide Strings gleich, wird 0 zurückgegeben. Ist der String x kleiner als der String y, ist der Rückgabewert kleiner als 0, und ist x größer als y, dann ist der Rückgabewert größer als 0. Ein Beispiel:

void String_Vergleich(char x[], char y[])
{
   int retvalue;
   retvalue = strcmp (x, y);
 
   if (retvalue == 0)
      printf("%s == %s\n",x, y);
   else
      printf("%s %c %s\n",x,( (retvalue < 0)?'<':'>'), y);
}

Dabei greift die Funktion auf ein lexikographisches Verfahren zurück, welches auch z.B. bei Telefonbüchern verwendet wird. Würde der String x nach einer lexikographischen Ordnung vor dem String y stehen, so ist er kleiner.

[Bearbeiten] strncmp

int strncmp(const char *x, const char *y, size_t n);

Diese Funktion arbeitet ähnlich wie die Funktion strcmp(), mit einem Unterschied, dass n Zeichen miteinander verglichen werden. Es werden die ersten n Zeichen von x und die ersten n Zeichen von y miteinander verglichen. Der Rückgabewert ist dabei derselbe wie schon bei strncmp().

Ein Beispiel:

#include <stdio.h>
#include <string.h>
 
int main()
{
   const char x[] = "aaaa";
   const char y[] = "aabb";
   int i;
 
   for(i = strlen(x); i > 0; i--)
      {
         if(strncmp( x, y, i) != 0)
            printf("Die ersten %d Zeichen der beiden Strings "\
                   "sind nicht gleich\n",i);
         else
            {
               printf("Ab Zeichen %d sind "\
                      "beide Strings gleich\n",i);
               break;
            }
      }
   return 0;
}

[Bearbeiten] strspn

Die Funktion strspn() gibt die Position des ersten Vorkommens eines Zeichens an, das nicht vorkommt. Die Syntax lautet:

int strspn(const char *s1, const char *s2);


Folgendes Beispiel gibt Ihnen die Position des Zeichens zurück, welches keine Ziffer ist:

  1. #include <stdio.h>
    
  2. #include <string.h>
    
  3.  
    
  4. int main()
    
  5. {
    
  6.    const char string[] = "7501234-123";
    
  7.    int pos = strspn(string, "0123456789");
    
  8.    printf("Die Position, an der keine Ziffer steht:");
    
  9.    printf(" %d\n",pos); // 7 
    
  10.    return 0;
    
  11. }
    

[Bearbeiten] strchr

char* strchr(char * string, int zeichen)

Die Funktion strchr (string char) sucht das erste Vorkommen eines Zeichens in einem String. Sie liefert entweder die Adresse des Zeichens zurück oder NULL, falls das Zeichen nicht im String enthalten ist.

Beispiel:

#include <stdio.h>
#include <string.h>
 
int main()
{
  char string[] = "Ein Teststring mit Worten";
  printf("%s\n",strchr(string, (int)'W'));
  printf("%s\n",strchr(string, (int)'T'));
  return 0;
}

Hier die Ausgabe des Programms:

Worten
Teststring mit Worten

[Bearbeiten] strlen

Zum Ermitteln der Länge eines String, kann man die Funktion strlen() verwenden. Die Syntax lautet wie folgt:

size_t strlen(const char *string1);

Mit dieser Syntax wird die Länge des adressierten Strings string1 ohne das Stringende-Zeichen zurückgegeben. Nun ein Beispiel zu strlen():

#include <stdio.h>
#include <string.h>
 
int main() {
   char string1[] = "Das ist ein Test";
   size_t length;
 
   length= strlen(string1);
   printf("Der String \"%s\" hat %d Zeichen\n",string1, length); 
     // Der String "Das ist ein Test" hat 16 Zeichen
   return 0;
}

[Bearbeiten] Gefahren

Bei der Verarbeitung von Strings muss man sehr vorsichtig sein, um nicht über das Ende eines Speicherbereiches hinauszuschreiben oder zu -lesen. Generell sind Funktionen wie strcpy() und sprintf() zu vermeiden und stattdessen strncpy() und snprintf() zu verwenden, weil dort die Größe des Speicherbereiches angegeben werden kann.

  1. #include <string.h>   // fuer Zeichenketten-Manipulation
    
  2. #include <stdio.h>    // fuer printf()
    
  3.  
    
  4. int main(void)
    
  5. {
    
  6.   char text[20];
    
  7.  
    
  8.   strcpy(text, "Dies ist kein feiner Programmtest"); //Absturzgefahr
    
  9.  
    
  10.   strncpy(text, "Dies ist ein feiner Programmtest", sizeof(text));
    
  11.   printf("Die Laenge ist %u\n", strlen(text)); //Absturzgefahr
    
  12.  
    
  13.   // also vorsichtshalber mit 0 abschliessen.
    
  14.   text[sizeof(text)-1] = 0;
    
  15.   printf("Die Laenge von '%s' ist %u \n", text, strlen(text));
    
  16.  
    
  17.   return 0;
    
  18. }
    

Die beiden Zeilen 8 und 11 bringen das Programm möglicherweise zum Absturz:

  • Zeile 8: strcpy() versucht mehr Zeichen zu schreiben, als in der Variable vorhanden sind, was möglicherweise zu einem Speicherzugriffsfehler führt.
  • Zeile 11: Falls das Programm in Zeile 8 noch nicht abstürzt, geschieht das evtl. jetzt. In Zeile 10 werden genau 20 Zeichen kopiert, was prinzipiell in Ordnung ist. Weil aber der Platz nicht ausreicht, wird die abschließende 0 ausgespart, was bedeutet, dass die Zeichenkette nicht terminiert ist. Die Funktion strlen() benötigt aber genau diese '\0', um die Länge zu bestimmen. Tritt dieses Zeichen nicht auf, kann es zu einem Speicherzugriffsfehler kommen.

Entfernt man die beiden Zeilen 8 und 11 ergibt sich folgende Ausgabe:
Die Laenge von 'Dies ist ein feiner' ist 19

Es ist klar, dass sich hier als Länge 19 ergibt, denn ein Zeichen wird eben für die 0 verbraucht. Man muss also immer daran denken, ein zusätzliches Byte dafür einzurechnen.

[Bearbeiten] Iterieren durch eine Zeichenkette

  1. #include <string.h>   // fuer Zeichenketten-Manipulation
    
  2. #include <stdio.h>    // fuer printf()
    
  3.  
    
  4.  /* Diese Funktion ersetzt in einer Zeichenkette ein Zeichen
    
  5.   * durch ein anderes. Der Rückgabewert ist die Anzahl der
    
  6.   * Ersetzungen */
    
  7. unsigned replace_character(char* string, char from, char to)
    
  8. {
    
  9.   unsigned result = 0;
    
  10.  
    
  11.   if (!string) return 0;
    
  12.  
    
  13.   while (*string != 0) {
    
  14.     if (*string == from) {
    
  15.       *string = to;
    
  16.       result++;
    
  17.     }
    
  18.     string++;
    
  19.   }
    
  20.   return result;
    
  21. }
    
  22.  
    
  23. int main(void)
    
  24. {
    
  25.   char text[50] = "Dies ist ein feiner Programmtest";
    
  26.   unsigned result;
    
  27.  
    
  28.   result = replace_character(text, 'e', ' ');
    
  29.   printf("%u : %s\n", result, text);
    
  30.  
    
  31.   result = replace_character(text, ' ', '#');
    
  32.   printf("%u : %s\n", result, text);
    
  33.  
    
  34.   return 0;
    
  35. }
    

Die Ausgabe lautet:

5 : Di s ist  in f in r Programmt st
9 : Di#s#ist##in#f#in#r#Programmt#st


[Bearbeiten] Die Bibliothek ctype.h

Wie wir bereits im Kapitel Variablen und Konstanten gesehen haben, sagt der Standard nichts über den verwendeten Zeichensatz aus. Nehmen wir beispielsweise an, wir wollen testen, ob in der Variable c ein Buchstabe gespeichert ist. Dazu verwenden wir die Anweisung

  if ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z')

Unglücklicherweise funktioniert das Beispiel zwar auf dem ASCII-Zeichensatz, nicht aber mit dem EBCDIC-Zeichensatz. Der Grund hierfür ist, dass die Buchstaben beim EBCDIC-Zeichensatz nicht hintereinander stehen.

Wer eine plattformunabhängige Lösung sucht, kann deshalb auf Funktionen der Standardbibliothek zurückgreifen. Ihre Prototypen sind alle in der Headerdatei <ctype.h> definiert. Für den Test auf Buchstabe können wir die Funktion int isalpha(int c) benutzen. Alle Funktionen, die in der Headerdatei ctype.h deklariert sind, liefern einen Wert ungleich 0 zurück wenn die entsprechende Bedingung erfüllt ist, andernfalls liefern sie 0 zurück.

Weitere Funktionen von ctype.h sind:

  • int isalnum(int c) testet auf alphanumerisches Zeichen (a-z, A-Z, 0-9)
  • int isalpha(int c) testet auf Buchstabe (a-z, A-Z)
  • int iscntrl(int c) testet auf Steuerzeichen (\f, \n, \t ...)
  • int isdigit(int c) testet auf Dezimalziffer (0-9)
  • int isgraph(int c) testet auf druckbare Zeichen
  • int islower(int c) testet auf Kleinbuchstaben (a-z)
  • int isprint(int c) testet auf druckbare Zeichen ohne Leerzeichen
  • int ispunct(int c) testet auf druckbare Interpunktionszeichen
  • int isspace(int c) testet auf Zwischenraumzeichen (Leerzeichen, \f, \n, \t ...)
  • int isupper(int c) testet auf Großbuchstaben (A-Z)
  • int isxdigit(int c) testet auf hexadezimale Ziffern (0-9, a-f, A-F)
  • int isblank(int c) testet auf Leerzeichen

Zusätzlich sind noch zwei Funktionen für die Umwandlung in Groß- bzw. Kleinbuchstaben definiert:

  • int tolower(int c) wandelt Groß- in Kleinbuchstaben um
  • int toupper(int c) wandelt Klein- in Großbuchstaben um
Persönliche Werkzeuge
In anderen Sprachen