Exkurs: Scanf und Sonderzeichen
Groß-/Kleinschreibung umwandeln
<string.h>
Im Beispiel “Datei einlesen” mussten wir die Länge eines Strings bestimmen. Diesen Schritt kann die Funktion strlen
übernehmen.
int str_len = strlen(my_string);
Wir erhalten so die Anzahl der (ASCII) Zeichen im String ohne den Nullchar am Ende.
Wollen wir zwei Strings aneinanderfügen, so können wir die strcat
(string concatenate) nutzen.
strcat(my_string, my_string2);
Die Funktion fügt den Inhalt von my\_string2
ans Ende von my\_string
an. Hier müssen wir darauf achten, dass my_string
genügend Speicher zur Verfügung steht.
char a[] = "Hallo ", b[] = "Welt.";
char * str
// +1 für den Nullchar
= malloc(strlen(a) + strlen(b) + 1);
// Initialisiere Ende des Strings an Stelle 0.
// Damit wird mit strcat()
// an Anfang des Strings kopiert.
str[0] = '\0';
strcat(str, a);
strcat(str, b);
printf("%s\n", str);
In obigem Code werden zwei statische Strings in einen dynamischen kopiert. Dafür nutzen wir strlen
, um die nötige Menge an Speicherplatz zu errechnen und strcat
für den Kopiervorgang.
Wollen wir Strings nicht aneinanderfügen, sondern kopieren, können wir strcpy
nutzen.
strcpy(my_string, my_string2)
Hier wird der Inhalt von my\_string2
in my\_string
kopiert. Dabei gilt es wieder auf den vorhandenen Speicherplatz zu achten.
Im obigen Beispielcode können wir diese beiden Zeilen
str[0] = '\0';
strcat(str, a);
auch durch einen Kopiervorgang ersetzen.
strcpy(str, a);
Wollen wir den Inhalt von zwei Strings auf Gleichheit prüfen, können wir strcmp
nutzen.
strcmp(my_string, my_string2)
Der Rückgabewert nimmt bei Gleichheit den Wert 0.
char a[] = "Hallo ", b[] = "Hallo";
if ( strcmp(a, b) == 0 ) {
printf("Gleich!\n");
} else {
printf("Nicht gleich!\n");
}
Hier nimmt es C aber ganz genau. Obiger Code gibt zum Beispiel “Nicht gleich” aus, da der String a
am Ende ein zusätzliches Leerzeichen hat.
Wir können Strings mit der Funktion strchr
nach Zeichen durchsuchen.
strchr(my_string, 'a')
Als Rückgabewert erhalten wir entweder einen Pointer auf das Zeichen im String, oder NULL
, falls das Zeichen nicht gefunden wurde.
Mit strrchr
können wir Strings auch rückwärts durchsuchen.
Im Header ctype.h
finden sich die Funktionen tolower(char)
und toupper(char)
, um Zeichen zu Groß- bzw. Kleinschreibung umzuwandeln.
Im selben Header gibt es auch einige Funktionen isdigit(char)
, isupper(char)
, etc, die überprüfen, ob ein Zeichen einer bestimmten Gruppe (Zahlen, Großbuchstaben, …) angehört. Das ist besonders für die Überprüfung von Nutzereingaben nützlich.
Mit folgendem Programm könnten wir für ein Programm, das als Kommandozeilenparameter eine Ganzzahl erwartet beispielsweise die Eingabe prüfen.
#include <stdio.h>
#include <ctype.h>
int main(int argc, char** argv) {
if ( argc < 2 ) {
printf("Usage: ./a.out 123\n");
return 1;
}
for ( int i = 0; argv[1][i] != 0; i += 1 ) {
if ( !isdigit( argv[1][i]) ) {
printf("Usage: ./a.out 123\n");
return 1;
}
}
}
Für ein solches Programm wollen wir den Parameter danach üblicherweise in eine Integer umwandeln. In stdlib.h
finden sich dazu einige Funktionen für die Standardtypen integer, float, double, etc. Diese Funktionen sind atoXX
benannt, wobei XX
dem format specifier entspricht. Die Funktion atof
wandelt Strings zu floats, atoi
zu integern um.
int para = atoi(argv[1]);
In die andere Richtung können wir Zahlen auch zu Strings umwandeln. Die Funktion sprintf
funktioniert analog zu printf
, speichert die Ausgabe aber in einen String.
sprintf(my_string, "%d %d\n", int_a, int_b)
Der Header string.h
bietet zusätzlich eine Funktion um den Speicherbereich von allgemeinen Arrays zu kopieren. Die Funktion memcpy(arr a, arr b, size)
kopiert size
Bytes von der Adresse b
an die Adresse a
.
double a[] = {1.0,2.0,3.0};
double b[] = {4.0,5.0,6.0};
for ( int i = 0; i < 3; i+=1 ) {
a[i] = b[i];
}
// Analog zu obigem Loop
memcpy(a,b,3*sizeof(double));