Programmieren mit C


Inhalt


Willkommen

Installation

Das Terminal

Exkurs: Scanf und Sonderzeichen

Exkurs: continue & break

Statische Arrays

Exkurs: sizeof

Dynamische Arrays

Exkurs: Speicherbereiche

Funktionen

Exkurs: Funktionen & Arrays

Kommandozeilenparameter

Structs

Dateien

Anwendung: Textdatei einlesen

Hintergrund: Unicode

Stringbibliothek

Länge bestimmen

Strings zusammenfügen

Strings kopieren

Strings vergleichen

Strings durchsuchen

Groß-/Kleinschreibung umwandeln

Zeichen prüfen

Typumwandlung

Bonus: Allgemeine Arrays kopieren

Ausblick

Dark Mode

Bibliothek: <string.h>

Länge bestimmen

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.

Strings zusammenfügen

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.

Strings kopieren

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

Strings vergleichen

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.

Strings durchsuchen

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.

Groß-/Kleinschreibung umwandeln

Im Header ctype.h finden sich die Funktionen tolower(char) und toupper(char), um Zeichen zu Groß- bzw. Kleinschreibung umzuwandeln.

Zeichen prüfen

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

Typumwandlung

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)

Bonus: Allgemeine Arrays kopieren

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