1 Theorie | |
→ | 1.1 Die Programmiersprache C |
Zeichenketten (engl. string) sind in C ein Feld von
char.
Das Ende einer Zeichenkette wird dabei durch ein
0-Byte markiert.
Der Text "Hallo" wird durch die Bytes für die Buchstaben 'H', 'a', 'l', 'l', 'o' und ein abschließendes 0-Byte dargestellt.
Werden in C-Quelltexten String-Literale (Strings in doppelten Anführungszeichen) verwendet, legt der C-Compiler ein char-Feld an, das den angegebenen Text und ein abschließendes 0-Byte enthält. An die Stelle des String-Literals tritt ein const-char-Zeiger auf den Feldanfang. Der Compiler darf das char-Feld in einem nur lesbaren Speicherbereich anlegen und optional Strings mit gleichem Text zusammenfassen.
Steht im Quelltext beispielsweise die Anweisung
printf("Hallo\n");
so legt der Compiler ein char-Array mit den Bytes 'H', 'a', 'l',
'l', 'o', '\n' und 0x00 an.
Die Funktion printf() erhält als Argument einen Zeiger auf
den Anfang dieses Feldes.
Wird ein Zeiger auf ein String-Literal gespeichert, muss berücksichtigt werden, dass der Inhalt des Strings nicht geändert werden darf. Es muss also ein Zeiger auf "const char" verwendet werden.
const char *test_ptr = "Hallo\n";
Für die Beispielzeile legt der Compiler in einem nur lesbaren
Speicherbereich ein anonymes Feld mit dem Inhalt
'H', 'a', 'l', 'l', 'o', '\n', 0x00
an und speichert die Adresse des Feldanfanges im Zeiger
test_ptr.
Anonym bedeutet, dass das Feld nicht über einen eigenen Namen
(C-Identifier) angesprochen werden kann, Zugriffe können nur über
die im Zeiger test_ptr gespeicherte Adresse erfolgen. Wird
der Zeiger test_ptr verändert, ist kein Zugriff auf das Feld mehr
möglich.
Das Schlüsselwort "const" wird weiter unten behandelt.
char test_string[] = { "Hallo\n" };
Es wird ein Feld test_string angelegt als eine Folge von char mit den Werten 'H', 'a', 'l', 'l', 'o', '\n' und 0x00. Das Feld hat also 7 Elemente, die 5 Buchstaben, das Newline (Zeilenwechsel) und das abschließende 0-Byte.
Dasselbe Feld könnte auch mit
char test_string[] = { 'H', 'a', 'l', 'l', 'o', '\n', 0x00 };
angelegt werden, was aber wesentlich umständlicher zu schreiben wäre.
Das nachfolgende Programm ex079 zeigt den Unterschied zwischen
Strings in einem initialisierten Feld von char und String-Pointern,
die auf anonyme, nur lesbare Felder von char zeigen.
Die Felder ta1 und ta2 werden als Feld von char
angelegt und mit den angegebenen Strings initialisiert. Diese
Felder sind änderbar. Da ta1 größer ist als ta2, kann
der in ta2 stehende String in das Feld ta1 kopiert
werden.
Die Pointer tp1 und tp2 zeigen auf anonyme
char-Felder mit den Inhalten
"Morgen ist Freitag, danach ist Wochenende." bzw.
"Heute ist Donnerstag.", die der C-Compiler in nur
lesbaren Speicherbereichen unterbringt. Der Versuch, den Inhalt des
Feldes, auf das tp2 zeigt, in das Feld zu kopieren, auf das
tp1 zeigt, führt daher zu einer
Speicherschutzverletzung.
Die Deklaration der Zeiger tp1 und tp2 als
const char *tp1 = "Morgen ist Freitag, danach ist Wochenende."; const char *tp2 = "Heute ist Donnerstag.";
hätte wenigstens zu einer Compiler-Warnung geführt.
/* ex079.c
Unterschied zwischen String als Array und String-Pointer.
*/
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
/* Zwei Strings, die als Arrays ta1 und ta2 angelegt werden. Veraenderlich.
*/
char ta1[] = { "Morgen ist Freitag, danach ist Wochenende." };
char ta2[] = { "Heute ist Donnerstag." };
/* Zwei Strings, die als Pointer ts1 und ts2 auf anonyme Array angelegt werden.
Der C-Compiler bringt die anonymen Arrays in nur lesbarem Speicher unter.
*/
char *tp1 = "Morgen ist Freitag, danach ist Wochenende.";
char *tp2 = "Heute ist Donnerstag.";
int
main(void)
{
/* Die Arrays ta1 und ta2 werden als normale Felder von char
angelegt, beide Felder sind les- und schreibbar.
Das Ueberschreiben von ta1 ergibt kein Problem.
*/
printf("ta2 nach ta1 kopieren:\n");
fflush(stdout);
strcpy(ta1, ta2);
printf("%s\n\n", ta1);
fflush(stdout);
/* Die Zeiger tp1 und tp2 zeigen auf anonyme Arrays, die der
C-Compiler in nur lesbarem Speicher unterbringt.
Ein Versuch, das Array zu aender, auf das tp1 zeigt, fuehrt
zu einer Speicherschutzverletzung.
*/
printf("tp2 nach tp1 kopieren (fuehrt zu Speicherschutzverletzung):\n");
fflush(stdout);
strcpy(tp1, tp2);
printf("%s\n\n", tp1);
fflush(stdout);
return 0;
}
/* vim: set ai sw=4 ts=4 : */
Da der C-Quelltext selbst nur ASCII-Zeichen enthalten darf, müssen Nicht-ASCII-Zeichen durch Backslash-Escape-Sequenzen angegeben werden:
\t | Tabulator Wird ein Tabulator in die Standardausgabe ausgegeben, wird mindestens eine Leerstelle gelassen, danach werden weitere Leerstellen hinzugefügt, bis die Position ohne Rest durch 8 teilbar ist. Werden Text-Dateien mit Tabulatoren in einem Editor — z.B. MS Visual Studio — bearbeitet, kann eine Tabulatorbreite eingestellt werden. Häufig werden hier die Werte 4 oder 8 verwendet. |
\n | Zeilenvorschub (Newline) Wechsel in eine neue Zeile. |
\r | Wagenrücklauf Aus historischen Gründen verwenden manche Betriebssysteme — wie z.B. Windows — am Zeilenende eine Kombination von Wagenrücklauf und Zeilenvorschub. Die Auftrennung in Wagenrücklauf und Zeilenvorschub geht zurück auf elektrische Schreibmaschinen und Fernschreiber, die hierfür zwei verschiedene Tasten hatten. |
\v | Vertikal-Tabulator |
\f | Form feed (Seitenvorschub). |
\a | Alarm Ausgabe eines Signaltones. |
\b | Backspace Löschen des letzten ausgegebenen Zeichens |
\\ | Einzelner Backslash Da ein Backslash eine Backslash-Sequenz einleitet, muss ein einzelner Backslash durch eine Backslash-Sequenz dargestellt werden. |
\' | Einfaches Anführungszeichen (wenn es in char-Literal verwendet wird). |
\" | Doppeltes Anführungszeichen (wenn es in String-Literal benutzt wird). |
\ooo | Byte als Oktalwert. Es müssen 1 bis 3 Oktalstellen angegeben werden. Beispiel: \141 bedeutet 1*82+4*81+1*80, also 1*64+4*8+1=97. Dies entspricht dem ASCII-Code für das Zeichen 'a'. |
\xXX | Byte als Hexadezimalwert. Für char müssen 1 bis 2 Hexadezimalstellen angegeben werden. Beispiel: \x61 bedeutet 6*161+1*160, also 6*16+1=97. Auch dies entspricht wieder dem ASCII-Code für das Zeichen 'a'. Für wchar_t müssen 1 bis 4 Hexadezimalstellen angegeben werden, wenn ein wchar_t 16 Bit breit ist bzw. 1 bis 8 Hexadezimalstellen, wenn ein wchar_t 32 Bit breit ist. |
\uXXXX \UXXXXXXXX |
Unicode-Zeichen als Hexadezimalwert. Es müssen genau 4 Hexadezimalstellen nach \u bzw. genau 8 Hexadezimalstellen nach \U angegeben werden. Diese Notation ist in C++ verfügbar sowie in C ab C-Standard C99. Angegeben werden können die Zeichen ab einschließlich U+00A0 mit Ausnahme des Bereiches von einschließlich U+D800 bis einschließlich U+DFFF. Unterhalb von U+00A0 können die Zeichen U+0024 ($), U+0040 (@) und U+0060 (')angegeben werden. Beispiel: Das Grad-Zeichen mit der Unicode-Position U+00B0 (0*163+0*162+11*161+0*160=176) passt noch in ein Byte, somit kann es wahlweise oktal als \260 (2*82+6*81+0*80=176) oder hexadezimal als \xB0 oder als Unicode-Zeichen \u00B0 dargestellt werden. Auf der UNICODE-Homepage 〈1〉 finden Sie Zeichentabellen mit der Zuordnung von Zeichen zu Hexadezimal-Codes. Die Tabelle "The Unicode Standard" → "Code Charts" → "Latin-1 Supplement" zeigt Sonderzeichen, wie z.B. deutsche Umlaute. Die Verwendung von Unicode-Zeichen oberhalb von U+00FF ist nur sinnvoll für:
|
Die nachfolgende Tabelle zeigt einige ausgewählte Unicode-Positionen.
Zeichen | Unicode-Position | Backslash-Sequenz |
---|---|---|
ä | U+00E4 | \u00E4 |
ö | U+00F6 | \u00F6 |
ü | U+00FC | \u00FC |
Ä | U+00C4 | \u00C4 |
Ö | U+00D6 | \u00D6 |
Ü | U+00DC | \u00DC |
ß | U+00DF | \u00DF |
€ | U+20AC | \u20AC |
Die Hexadezimal- oder Oktaldarstellung wird empfohlen, wenn ein
bestimmter Bytewert angegeben werden soll.
Die Unicodedarstellung wird empfohlen, wenn ein bestimmtes
Textzeichen erzeugt werden soll. Der Compiler kann dann den
Bytewert bzw. die Bytewerte benutzen, die dieses Zeichen im
Zeichensatz des Zielsystems repräsentieren.
Mit dem Zusatz "const" unmittelbar vor oder nach dem Datentyp in einer Deklaration kann festgelegt werden, dass die entsprechenden Daten nicht änderbar sind.
Im Beispiel
const char test_string[] = { "Hallo" };
bedeutet "const char", dass test_string ein Feld von nicht änderbaren Buchstaben ist.
Das Schlüsselwort "const" bezieht sich immer auf
"das Nächstgelegene".
In
const char *ptr1 = test_string;
Ist ptr1 ein Zeiger auf konstante Buchstaben.
"const" kann auch nach dem Datentyp stehen, die Definitionen
char const test_string[] = { "Hallo" }; char const *ptr1 = test_string;
sind identisch zu den vorangegangenen.
Hingegen in
char * const ptr2 = anderer_string;
steht das "const" näher am Variablennamen, deshalb ist ptr2 ein konstanter Zeiger auf anderer_string. D.h. ptr2 kann nicht geändert werden, die Buchstaben, auf die ptr2 zeigt sind aber änderbar.
Im Beispiel
const char * const ptr3 = test_string;
ist ptr3 ein Zeiger auf konstante Buchstaben, der Zeiger ptr3 ist selbst ebenfalls konstant.
Verwendet ein Programm Strings, die nicht modifiziert werden,
sollten diese als "const" markiert werden. Damit kann der Compiler
auch diese Felder in nur lesbaren Speicherbereichen
unterbringen.
Laufen mehrere Instanzen des Programmes (z.B. in verschiedenen
Fenstern), werden die nur lesbaren Speicherbereiche nur einmal in
den Hauptspeicher geladen und dann in den Adressbereich aller
Programminstanzen eingeblendet. Von initialisierten aber änderbaren
Speicherbereichen hat jede Programminstanz eine eigene separate
Kopie.
Die Verwendung von "const" für nicht modifizierbare Daten sorgt für
sparsamen Umgang mit dem Hauptspeicher.
const char test_string[] = { "Hallo" };
Mitunter werden String-Felder angelegt, z.B. um Hilfetexte oder Versionsinformationen auszugeben. Hier ein Beispiel für den richtigen Einsatz von "const" für diesen Zweck, hilfe_text ist hier ein Feld von Zeigern. Jeder Zeiger enthält die Adresse eines anonymen (und damit nur lesbaren und deshalb mit "const" markierten) Feldes von char, die einzelnen Elemente von hilfe_text sind ebenfalls nicht änderbar und somit "const".
const char * const hilfe_text[] = { "Benutzung:" "----------" "copy Quelldatei Zieldatei" "", "Quelldatei Name der Datei, die kopiert werden soll.", "Zieldatei Name der Kopie, die erzeugt werden soll.", NULL };
Wird auf dieses Feld zugegriffen, muss auch der zum Durchmustern des Feldes benutzte Zeiger mit entsprechenden const-Qualifizierern versehen sein.
/* Testprogramm mit Feld von String-Literalen */
/* Copyright (C) 2014-2017 - HS Schmalkalden. All rights reserved. */
#include <stdio.h>
#include <string.h>
/** Hilfetext, umfasst mehrere Zeilen.
*/
const char * const hilfe_text[] = {
"Benutzung:",
"----------",
"copy Quelldatei Zieldatei",
"",
"Quelldatei Name der Datei, die kopiert werden soll.",
"Zieldatei Name der Kopie, die erzeugt werden soll.",
NULL
};
/** Hauptprogramm.
@return 0 bei Erfolg, alle anderen Werte bedeuten Fehler.
*/
int
main(void)
{
const char * const *ptr;
ptr = hilfe_text;
while(*ptr) {
printf("%s\n", *(ptr++));
}
fputc('\n', stdout);
return 0;
}
/* vim: set ai sw=4 ts=4 expandtab : */
Auch Argumente einer Funktion können im Prototyp bzw. Funktionskopf als const markiert werden, z.B. im Prototyp der Funktion
char * strcpy(char *dest, const char *src);
zum Kopieren von Strings.
In diesem Beispiel bedeutet das, dass die Funktion strcpy()
die Buchstaben in dem Feld, auf das src zeigt, nicht ändern
darf (und dies auch nicht tut).
"const" kann auch im Rückgabetyp verwendet werden, z.B.:
const char * irgendeinefunktion(char const *src);
Dies bedeutet, dass der Rückgabewert der Funktion ein Zeiger auf konstante Buchstaben ist.
#include <string.h>
Wollen Sie die nachfolgenden Funktionen nutzen, müssen Sie die Header-Datei "string.h" mit einbinden.
Im nachfolgenden Text werden nur ausgewählte Funktionen zur Arbeit mit Strings vorgestellt, eine vollständige Auflistung wäre zu umfangreich.
size_t strlen(const char *s);
Die Funktion gibt die Länge des übergebenen Strings als Ergebnis zurück. Dabei wird das abschließende 0-Byte nicht mitgezählt.
char * strcpy(char *destination, const char *source);
Diese Funktion kopiert den String, auf dessen Anfang der Zeiger
source zeigt, in den Speicherbereich, auf dessen Anfang der
Zeiger destination zeigt.
Die Buchstaben, auf die source zeigt, werden nicht geändert.
Im Zielbereich werden Änderungen vorgenommen, deshalb ist
destination nicht als const markiert.
Diese Funktion prüft nicht, ob der Zielpuffer groß genug ist, um
den Text aufzunehmen.
Diese Prüfung muss vom Programmierer vorgenommen werden, bevor
strcpy() verwendet wird.
Da die Funktion strlen() die String-Länge ohne
abschließendes 0-Byte — welches aber mit kopiert wird — angibt,
muss die Puffergröße größer sein als der von strlen()
ermittelte Wert (nicht: größer oder gleich).
Im Beispiel ex012.c wird der erste Test-String erfolgreich kopiert, der zweite String ist zu groß für den Puffer.
/* Testprogramm zur Demonstration von strcpy */
/* Copyright (C) 2014-2017 - HS Schmalkalden. All rights reserved. */
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#include <stdio.h>
#include <string.h>
/** Kurzer Test-String, passt in Puffer.
*/
char const teststring1[] = { "Montag" };
/** Langer Test-String, passt nicht in Puffer.
*/
char const teststring2[] = { "Sonnabend" };
/** Hauptprogramm.
@return 0 bei Erfolg, alle anderen Werte bedeuten Fehler.
*/
int
main(void)
{
char puffer[7];
/* Versuch, teststring1 in den Puffer zu kopieren.
*/
if(sizeof(puffer) > strlen(teststring1)) {
strcpy(puffer, teststring1);
printf("Test-String 1 wurde kopiert!\n");
}
else {
printf("FEHLER: Test-String 1 ist zu gross fuer Puffer!\n");
}
/* Versuch, teststring2 in den Puffer zu kopieren.
*/
if(sizeof(puffer) > strlen(teststring2)) {
strcpy(puffer, teststring2);
printf("Test-String 2 wurde kopiert!\n");
}
else {
printf("FEHLER: Test-String 2 ist zu gross fuer Puffer!\n");
}
return 0;
}
/* vim: set ai sw=4 ts=4 expandtab : */
Bei der Programmierung mit Visual Studio unter Windows steht die Funktion
errno_t strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource);
zur Verfügung, diese übernimmt den Größentest mit.
Microsoft propagiert die Verwendung ausschließlich dieser Funktion
anstelle von strcpy() und gibt bei Verwendung von
strcpy() Warnungen aus.
Um strcpy() verwenden zu können, muss die Konstante
_CRT_SECURE_NO_WARNINGS auf einen Wert ungleich 0 definiert werden,
bevor die Include-Datei string.h eingebunden wird.
char * strcat(char *dest, const char *src);
hängt den Inhalt der Zeichenkette, auf die src zeigt, an die bereits im Puffer dest stehende Zeichenkette an. Dabei muss in dest eine bereits mit einem 0-Byte abgeschlossene Zeichenkette stehen, oder das erste Byte von dest muss ein 0-Byte sein.
Diese Funktion prüft nicht, ob der Zielpuffer groß genug ist, um
den Text aufzunehmen.
Diese Prüfung muss vom Programmierer vorgenommen werden, bevor
strcat() verwendet wird.
Dabei muss die Summe aus der Länge des bereits im Zielpuffer
vorhandenen Strings und der Länge des anzuhängenden Strings kleiner
sein als die verfügbare Puffergröße.
/* Testprogramm zur Demonstration von strcat */
/* Copyright (C) 2014-2017 - HS Schmalkalden. All rights reserved. */
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#include <stdio.h>
#include <string.h>
/** Satzanfang, wird zuerst in Puffer kopiert.
*/
char const satzanfang[] = { "Heute ist: "};
/** Kurzer Test-String, passt noch nach Satzanfang in Puffer.
*/
char const teststring1[] = { "Montag" };
/** Langer Test-String, passt nicht nach Satzanfang in Puffer.
*/
char const teststring2[] = { "Sonnabend" };
/** Hauptprogramm.
@return 0 bei Erfolg, alle anderen Werte bedeuten Fehler.
*/
int
main(void)
{
char puffer[18];
/* Satzanfang in Puffer kopieren, danach Test-String 1 anhaengen.
*/
printf("Test-String 1\n");
if (sizeof(puffer) > strlen(satzanfang)) {
strcpy(puffer, satzanfang);
if (sizeof(puffer) > (strlen(puffer) + strlen(teststring1))) {
strcat(puffer, teststring1);
printf("Test-String erfolgreich kopiert.\n");
}
else {
printf("FEHLER: Zielpuffer ist zu klein!\n");
}
}
else {
printf("FEHLER: Zielpuffer ist zu klein!\n");
}
/* Satzanfang in Puffer kopieren, danach Test-String 2 anhaengen.
*/
printf("Test-String 2\n");
if (sizeof(puffer) > strlen(satzanfang)) {
strcpy(puffer, satzanfang);
if (sizeof(puffer) > (strlen(puffer) + strlen(teststring2))) {
strcat(puffer, teststring2);
printf("Test-String erfolgreich kopiert.\n");
}
else {
printf("FEHLER: Zielpuffer ist zu klein!\n");
}
}
else {
printf("FEHLER: Zielpuffer ist zu klein!\n");
}
return 0;
}
/* vim: set ai sw=4 ts=4 expandtab : */
Bei der Programmierung mit Visual Studio unter Windows steht die Funktion
errno_t strcat_s(char *strDestination, size_t numberOfElements, const char *strSource);
zur Verfügung, diese übernimmt den Größentest mit.
Microsoft propagiert die Verwendung ausschließlich dieser Funktion
anstelle von strcat() und gibt bei Verwendung von
strcat() Warnungen aus.
Um strcat() verwenden zu können, muss die Konstante
_CRT_SECURE_NO_WARNINGS auf einen Wert ungleich 0 definiert werden,
bevor die Include-Datei string.h eingebunden wird.
int strcmp(const char *s1, const char *s2);
Die Funktion vergleicht zwei Strings und gibt einen positiven Wert zurück, wenn s1 lexikographisch größer ist als s2. Sind beide Strings gleich, ist der Rückgabewert 0. Ist s1 lexikographisch kleiner als s2, wird ein negativer Wert zurückgegeben. Die Funktion strcmp() unterscheidet Groß- und Kleinschreibung.
Für den Vergleich ohne Unterscheidung von Groß- und Kleinschreibung ist unter Windows die Funktion stricmp() und unter Linux/UNIX die Funktion strcasecmp() vorhanden.
char * strchr(const char *s, int c);
Die Funktion sucht das erste Vorkommen des Zeichens c im
String s und gibt einen Zeiger auf das gefundene Zeichen
zurück.
Ist das Zeichen nicht im String enthalten, gibt die Funktion NULL
zurück.
Für die Suche nach dem letzten (am weitesten rechts stehenden) Vorkommen kann die Funktion
char * strrchr(const char *s, int c);
verwendet werden.
Auch hier wird nur eine Auswahl vorgestellt.
#include <ctype.h>
Die Header-Datei "ctype.h" enthält Funktionen für die Arbeit mit einzelnen Zeichen.
Die Funktionen arbeiten mit int-Werten. In diesen Werten sind
die Buchstaben als unsigned char dargestellt, nehmen also den
Bereich von 0 bis 255 ein.
Einige Ein-/Ausgabe-Funktionen (die später noch behandelt werden)
geben den speziellen Wert EOF (-1) zurück, wenn keine Buchstaben
mehr in der Eingabe vorhanden sind, daher die Verwendung des
Datentyps int.
Sollen diese Funktionen mit Buchstaben vom Type "char" benutzt
werden, so muss der Wert erst zu "unsigned char" konvertiert
werden, bevor er zu int konvertiert wird.
Andernfalls würden Zeichen aus dem Bereich 0x80...0xFF
fehlerhafterweise zu negativen Werten konvertiert.
int toupper(int c); int tolower(int c);
Diese Funktionen wandeln Kleinbuchstaben zu Großbuchstaben bzw. umgekehrt und geben alle anderen Zeichen unverändert zurück.
int isascii(int c);
Die Funktion überprüft, ob c ein 7-Bit unsigned char aus dem ASCII-Zeichensatz ist.
Die nachfolgenden Funktionen/Makros dürfen nur gemeinsam mit isascii() angewandt werden, also z.B.:
char c; c = ...; if ((isascii((unsigned char)c)) && (isalnum((unsigned char)c))) { /* ... Zeichen ist alphanumerisch ... */ }
Quelle: CERT C Coding Standard 〈2〉
char c; c = ... if ((isascii((unsigned char)c)) && (isprint((unsigned char)c))) { ... }Dies gilt für alle Funktionen, die int-Werte verarbeiten, um ein evtl. vorkommendes EOF mit abzudecken.
char *pointer_to_test_string = "Hallo";Richtig:
const char *pointer_to_test_string = "Hallo";
char test_string[5] = { "Hallo" };Richtig:
char test_string[] = { "Hallo" };Hier kann es sehr leicht zum Fehler kommen, dass beim Auszählen das abschließende 0-Byte vergessen wird. Daher die Größenbestimmung besser dem Compiler überlassen.
size_t strlcpy(char *dest, const char *src, size_t size);vorhanden.
char *strncpy(char *dest, const char *src, size_t n);sieht zwar vom Prototyp her ähnlich aus wie strlcpy() hat aber Nachteile.
dest[sizeof(dest)-1] = '\0';ausführen!
/* Testprogramm zur Demonstration von strncpy */
/* Copyright (C) 2014-2017 - HS Schmalkalden. All rights reserved. */
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#include <stdio.h>
#include <string.h>
/** Kurzer Test-String, passt in Puffer.
*/
char const teststring1[] = { "Montag" };
/** Langer Test-String, passt nicht in Puffer.
*/
char const teststring2[] = { "Sonnabend" };
/** Hauptprogramm.
@return 0 bei Erfolg, alle anderen Werte bedeuten Fehler.
*/
int
main(void)
{
char puffer[7];
strncpy(puffer, teststring1, sizeof(puffer));
puffer[sizeof(puffer)-1] = '\0';
printf("Puffer: \"%s\"\n", puffer);
strncpy(puffer, teststring2, sizeof(puffer));
puffer[sizeof(puffer)-1] = '\0';
printf("Puffer: \"%s\"\n", puffer);
return 0;
}
/* vim: set ai sw=4 ts=4 expandtab : */
1 | http://www.unicode.org |
2 | http://www.securecoding.cert.org |