Alle Leerzeichen aus einem Eingabetext entfernen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
 
int main(int argc, char* argv[])
{
	unsigned char i = 0;
	/* Eingabe-Maximum: 254 Zeichen */
	unsigned char eingabe[255];
 
	/* Text einlesen */
	printf("Eingabe:\n");
	/* Einlesen der Eingabe mit 255 Chars in "stdin".
	   stdin ist eine Datei, mit dem Inhalt der Tastaur. */
	fgets(eingabe,255,stdin);
 
	/* Solange der Text noch nicht zu Ende ist */
	while(eingabe[i] != '\0')
	{
		/* Wenn Zeichen ein Leerzeichen ist */
		if(eingabe[i] == 32)
		{
			i++;
			continue;
		}
		/* sonst */
		else
			printf("%c",eingabe[i]);
		/* String weiter parsen */
		i += 1;
	}
 
	printf("\n");
	return 0;
}

Anwendung von continue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
 
int main(int argc, char* argv[])
{
	unsigned char i = 0;
	for(i = 1; i < 101; i++) /* 100 Durchläufe */
	{
		printf("\nZahl: %2i",i);
 
		if((i%10 != 0))		 /* Nächster Schleifendurchlauf, */
			continue;	 /* wenn nicht durch 10 teilbar  */
 
		printf("\n");
		printf("\nHurra!");
		printf("\nDie Zahl %i war durch Zehn teilbar.",i);
		printf("\n");
	}
 
	return 0;
}

Warning: This function or variable may be unsafe.

Die Warnung „This function or variable may be unsafe.“ erhält man häufig in Microsoft Visual Studio bei der Verwendung von älteren Stringfunktionen wie etwa strcpy. Es wird einem vorgeschlagen anstelle von strcpy die Funktion strcpy_s zu benutzen, welche vor Pufferüberläufen schützt. Allerdings ist strcpy_s noch kein durchgesetzter ANSI-C-Standard, weshalb manche C-Compiler (z.B. unter Unix/Linux-Systemen) diese Funktion nicht kennen.

Um massenkompatibel zu sein und die Fehlermeldung zu unterdrücken empfiehlt es sich deshalb _CRT_SECURE_NO_WARNINGS zu definieren. Diese Konstante muss als Präprozessor-Direktive (also als ein Ding mit einem # davor) noch vor den #include Befehlen angegeben werden.

Beispiel:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

Eine elgante Variante für die Compilerproblematik ist die Abfrage, ob es sich beim Compiler um Microsoft Visual Studio handelt (wenn ja, dann strcpy_s benutzen) oder nicht (dann strcpy benutzen):

Beispiel:

#ifdef _MSC_VER
/* Anweisungen mit strcpy_s */
#else
/* Anweisungen mit strcpy */
#endif

Anwendung von malloc

Um sicherzustellen, dass für eine Anwendung genügend Speicher zum Abspeichern von Daten zur Verfügung steht, ist es schlau, einen gewissen Speicherbereich zu reservieren. Dabei hilft uns in C das Schlüsselwort malloc (engl. memory allocation). Das folgende Beispiel macht die Verwendung von malloc deutlich:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdlib.h>	/* Für malloc und free */
 
int main(int argc, char *argv[])
{
	long double* ptr;
	ptr = NULL;
	ptr = (long double*)malloc(sizeof(long double));
 
	printf("Adr. %u \n",ptr);	/* Adresse: 3420832 */
	printf("Adr. %u \n",ptr+1);	/* Adresse: 3420840 */
 
	free(ptr);
 
	return 0;
}

01: Einbindung der Standard Ein-/Ausgabe (stdio.h), damit das Schlüsselwort NULL verwendet werden kann.
02: Einbindung der Standard-Bibliothek (stdlib.h), damit malloc und free verwendet werden können.
06: Deklaration eines Pointers, der auf den Datentyp long double (8 Byte groß) zeigt.
07: Der Pointer ptr wird mit dem Schlüsselwort NULL initialisiert. Er zeigt also auf keinen Speicherbereich.
08: Die Funktion malloc reserviert mit sizeof einen Speicherplatz, der so groß ist, dass der Datentyp long double (8 Byte) hinein passt. Danach liefert malloc die Adresse dieser reservierten Speicherzelle als Integer-Wert zurück. Weil unser Pointer ptr aber vom Typ long double* (und nicht Integer) ist, muss die Rückgabe von malloc noch mit (long double*) gecastet werden, da sonst eine Warnung ausgegeben wird.
10: Die Adresse der Speicherzelle von ptr erhalten wir durch die Ausgabe von ptr als vorzeichenlose Ganzzahl (%u). Ein beispielhafter Wert für eine solche Adresse ist 3420832 (von Programmaufruf zu Programmaufruf unterschiedlich).
11: ptr wird um eins erhöht. Dadurch erhalten wir die Adresse der Speicherzelle nach ptr. Der Wert dieser nachfolgenden Speicherzelle ist nicht 3420831 (wie vielleicht vermutet), sondern 3420840. Also gleich 8 Zahlen höher, da ptr auf einen Bereich von 8 Byte (long double) zeigt.
13: Mit free(ptr) wird der von ptr reservierte Speicherbereich wieder frei gegeben.

Hinweis: Eine Pointervariable ist eine Variable, deren Wert eine Adresse ist.

Anwendung von typedef

Das Schlüsselwort typedef wird in C dazu verwendet, um einem Datentypen einen vereinfachten Namen zu geben. Das eignet sich besonders bei der Verwendung von Strukturen. Anhand von zwei Beispielen wird dies deutlicher:

Beispiel ohne typedef:

struct player
{
    char name[20];
    unsigned int number;
    unsigned int score;
};

Erzeugung eines Pointers auf die Datenstruktur „player“:

struct player *pPlayer = NULL;

Beispiel mit typedef:

typedef struct player
{
    char name[20];
    unsigned int number;
    unsigned int score;
} PLAYER;

Erzeugung eines Pointers auf die Datenstruktur „player“:

PLAYER *pPlayer = NULL;

Bei Anwendung einer Typdefinition muss jetzt nur noch das Schlüsselwort PLAYER (anstatt struct player) verwendet werden, was die Schreibweise und Code-Übersichtlichkeit wesentlich angenehmer macht.

Hinweis:: Es gibt noch eine weitere Möglichkeit eine Typdefinition durchzuführen, undzwar mit einer #define Konstanten am Anfang des Programms. Für das oben dargestellte Beispiel würde das so aussehen:

#define PLAYER struct player

Der Vorteil von #define ist, dass der Compiler eine einfache Ersetzung durchführen kann, wofür kein zusätzlicher Speicher reserviert werden muss.