|
kann man auch schreiben
char s[] = "string";
In C gibt es keine speziellen Sprachelemente für die Manipulation von Zeichenketten.
Es existieren jedoch in der C-Standardbibliothek eine Reihe von Funktionen zur
Stringbearbeitung.
- Funktionen zum Kopieren von Strings und Zeichenarrays
- Funktionen zum Aneinanderhängen von Strings
- Funktionen zum Vergleich von Strings und Zeichenarrays
- Funktionen zum Suchen nach Zeichen und Zeichenfolgen in Strings und Zeichenarrays
- Funktion zur Ermittlung der Länge eines Strings
- Funktion zum Füllen eines Arrays mit einem Zeichen
- Funktion zur Ermittlung der zu einer Fehlernummer gehörenden Fehlermeldung
Die entsprechenden Funktions-Deklarationen befinden sich in der Standard-Header-Datei
<string.h>. Diese ist daher bei Verwendung der Funktionen mittels
#include <string.h>
einzubinden. In <string.h> ist auch der von einigen Funktionen verwendete
Datentyp size_t definiert. Dies ist der "natürliche" unsigned-Typ, d. h. der Typ,
den der sizeof-Operator liefert.
Da in C Array-Grenzen-Überschreitungen nicht überprüft werden, liegt es am Programmierer
einen Array-Überlauf zu verhindern. Im ANSI-Standard ist lediglich festgelegt, daß
das Überschreiten von Array-Grenzen zu einem undefinierten Verhalten führt.
Alle Kopierfunktionen (siehe unten) setzen voraus, daß sich der Quell- und der
Zielbereich nicht überlappen. Im Falle der Überlappung ist das Verhalten undefiniert.
Bibliothek zum Test von Zeichen: <ctype.h>
Das Argument der folgenden Funktionen ist jeweils ein int dessen Wert
entweder EOF oder als unsigned char darstellbar sein muß.
Der Rückgabewert ist ein int, wobei dieser gleich Null ist, wenn das
Argument c die Bedingung nicht erfüllt, ansonsten ist er ungleich Null.
islower(c) | Kleinbuchstabe |
isupper(c) | Großbuchstabe |
isalpha(c) | Klein- oder Großbuchstabe |
isdigit(c) | Dezimalzahl |
isalnum(c) | Klein- oder Großbuchstabe oder Dezimalzahl |
iscntrl(c) | Control-Zeichen |
isgraph(c) | druckbares Zeichen außer space |
isprint(c) | druckbares Zeichen mit space |
ispunct(c) | druckbares Zeichen außer space, Buchstabe und Ziffern |
isspace(c) | space, formfeed, newline, carriage return, tab, vertical tab |
isxdigit(c) | Hexadezimalzahl |
Achtung: Die deutschen Umlaute und das "ß" sind keine Buchstaben im
obigen Sinne!!
In diesem Headerfile sind außerdem noch zwei Funktionen zur Konvertierung von
Buchstaben enthalten:
int tolower(int c) | konvertiert c zu Kleinbuchstaben |
int toupper(int c) | konvertiert c zu Großbuchstaben |
Das folgende Programm gibt für eine eingegebene ganze Zahl zwischen 0 und 999
das entsprechende Zahlwort aus (z. B. für den automatischen Druck von Schecks).
Es demonstriert die Initialisierung und Anwendung von Character-Arrays
(Zeichenketten). Die Denkarbeit bei der Konzeption besteht darin, daß man bei der
Einerstelle nicht bei "9" aufhören darf, sondern man die Werte von 0 bis 19 verwenden
muß.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
/****************** Zahlwörtertabellen ***************************/
char low [20][10] = { "null", "eins", "zwei", "drei", "vier", "fünf",
"sechs", "sieben", "acht", "neun", "zehn",
"elf", "zwölf", "dreizehn", "vierzehn",
"fünfzehn", "sechzehn", "siebzehn",
"achtzehn", "neunzehn" };
char ten [10][10] = { "", "", "zwanzig", "dreißig", "vierzig",
"fünfzig", "sechzig", "siebzig",
"achtzig", "neunzig" };
char hun [10][15] = { "", "einhundert", "zweihundert", "dreihundert",
"vierhundert", "fünfhundert", "sechshundert",
"siebenhundert", "achthundert", "neunhundert" };
/*****************************************************************/
int num;
printf("\nZahl: ");
scanf("%d",&num);
if (num < 20) /* 0 <= num < 20 */
printf("%s\n", low[num]);
else if (num < 100) /* 20 <= num < 100 */
{
if ((num % 10) == 0) /* Keine Einer */
printf("%s\n", ten[num/10]);
else if ((num % 10) == 1) /* Einerziffer 1 */
printf("einund%s\n", ten[num/10]);
else /* andere Einer */
printf("%sund%s\n", low[num%10], ten[num/10]);
}
else /* 100 <= num < 1000 */
{
if ((num%100) == 0) /* keine 1er, keine 10er */
printf("%s\n", hun[num/100]);
else if ((num%100) < 20) /* H01 bis H19 */
printf("%s%s\n", hun[num/100], low[num%100]);
else if ((num%10) == 0) /* letzte Ziffer 0 */
printf("%s%s\n", hun[num/100], ten[(num%100)/10]);
else if ((num%10) == 1) /* letzte Ziffer 1 */
printf("%seinund%s\n", hun[num/100], ten[(num%100)/10]);
else /* sonst. Zahlen */
printf("%s%sund%s\n", hun[num/100], low[num%10], ten[(num%100)/10]);
}
return(0);
}
Für die Bearbeitung von Zeichenketten gibt es eine umfangreiche Funktionsbibliothek:
Bibliothek mit String-Funktionen: <string.h>
Wie schon der Name sagt, werden in diesem Header Funktionen zur Manipulation
von Strings deklariert. Dabei werden folgende Typkonventionen benutzt:
char *s, *t;
const char *cs, *ct;
int c;
size_t n;
char *strcpy(s,ct) |
kopiert ct zu s inklusive dem abschließenden '\0'.
Zurückgegeben wird s. |
char *strncpy(s,ct,n) |
kopiert höchstens n Zeichen des Strings ct zu s
und liefert s zurück, wobei wie üblich mit '\0' terminiert
wird. |
char *strcat(s,ct) |
hängt ct an s an und liefert s zurück. |
char *strncat(s,ct,n) |
hängt höchstens n Zeichen von ct an s an,
terminiert mit '\0' und liefert s zurück. |
int strcmp(cs,ct) |
vergleicht cs und ct. Der Rückgabewert ist 0, wenn
die beiden Strings identisch sind, negativ, wenn cs<ct ist und positev, wenn
cs>ct ist, wobei das < und > im lexikalischen Sinne
verstanden wird, d.h. es wird Buchstabe für Buchstabe verglichen und geprüft, welcher
als erster im Alphabet steht, wobei wiederum Großbuchstaben vor Kleinbuchstaben
kommen (ASCII-Code). |
int strncmp(cs,ct,n) |
Im wesentlichen dasselbe wie zuvor, nur daß diesmal höchstens n
Zeichen verglichen werden. |
char *strchr(cs,c) |
liefert Pointer zum ersten Auftreten von c in cs zurück,
oder NULL wenn c nicht auftritt. |
char *strrchr(cs,c) |
liefert Pointer zum letzten Auftreten von c in cs zurück,
oder NULL wenn c nicht auftritt. |
char *strstr(cs,ct) |
liefert Pointer zum ersten Auftreten des Strings ct
in cs zurück oder NULL wenn ct nicht auftritt. |
size_t strlen(cs) |
liefert die Länge des Strings cs zurück. |
Beispiel für Strungbearbeitung: Stringpositeon ermitteln
Alle Operationen werden ohne Bibliotheksfunktionen und ohne Pointer ausgeführt.
#include <stdio.h>
#include <stdlib.h>
main()
{
int i, c;
char object[120], target[120], /* Suchstring, Quellstring */
hilf[120]; /* Hilfs-String fuer Tausch */
int opos, tpos, ergpos, /* Positeonen */
olen, tlen, hlen; /* Laengen */
do
{
printf("Erster String : ");
i = 0; /* String zeichenweise lesen */
while ((c = getchar()) != EOF && c != '\n')
object[i++] = c;
object[i] = '\0'; olen = i; /* Laenge gleich speichern */
if (c != EOF) /* Ctrl-D eingegeben ? */
{
printf("Zweiter String: ");
i = 0;
while ((c = getchar()) != EOF && c != '\n')
target[i++] = c;
target[i] = '\0'; tlen = i;
/* Suche immer den kuerzeren im laengeren String */
if (strlen(object) > strlen(target))
/* dann beide Strings vertauschen */
{
i = 0; /* object --> hilf */
while ((hilf[i]=object[i]) != '\0') i++;
i = 0; /* target --> object */
while ((object[i]=target[i]) != '\0') i++;
i = 0; /* hilf --> target */
while ((target[i]=hilf[i]) != '\0') i++;
hlen = olen; olen = tlen; /* und die Laengen auch */
tlen = hlen;
}
/* Beginn der Suche */
tpos = 0;
while (tlen != 0 && tpos < (tlen-olen+1))
{ /* Solange objet in target Platz hat */
opos = 0;
while ((target[tpos+opos] == object[opos]) && (opos < olen))
opos++; /* vergleichen ab tpos */
if (opos >= olen) /* object in target - fertig */
{
ergpos = tpos; /* Positeon merken */
tpos = tlen; /* sorgt fuer Abbruch */
}
else
ergpos = -1; /* nicht gefunden */
tpos++; /* sonst naechste Pos. */
}/*endwhile (tlen != 0...) */
/* Ausgabe */
if (ergpos < 0)
printf("Kein String ist Teilstring des anderen!");
else
printf("'%s' in '%s' ab Pos. %d enthalten",
object,target,ergpos);
}/* endif (c != EOF) */
printf("\n");
}
while (c != EOF); /* bis Ctrl-D eingegeben */
}
Dieses Programm ist sehr ""ausführlich" programmiert. Das folgende Programm
ist nicht nur etwas kürzer, sondern es werden vor allem zwei sinnvolle Funktionen
definiert. Das Programm sucht alle Zeilen aus der Standardeingabe, die ein bestimmtes
Suchmuster enthalten.
# include <stdio.h>
# define MAXLINE 1000 /* Maximale Zeilenlaenge */
int main(void)
{
char line[MAXLINE];
while (getline(line,MAXLINE) > 0)
if (index(line,"the") > 0)
printf("%s",line);
return 0;
}
int getline(char s[], int lim)
/* Eingabezeile mit max. lom Zeichen in s ablegen, Laenge liefern */
{
int c,i;
i = 0;
while (--lim>0 && (c=getchar()) != EOF && c!='\n')
s[i++] = c;
if (c == '\n') s[i++] = c;
s[i] = '\0';
return(i);
}
index (char s[],char t[])
/* Positeon von t in s liefern, -1 falls nicht da */
{
int i, j, k;
for (i = 0; s[i] != '\0'; i++)
{
for (j = i, k = 0; t[k] != '\0' && s[j] == t[k]; j++,k++)
;
if (t[k] == '\0') return(i);
}
return(-1);
}
Zum Abschluß noch ein völlig unnützes Programm:
Es gibt auf die Eingabe eines Geburtstages das entsprechende Tierkreiszeichen aus.
#include <stdio.h>
int main(void)
{
/* Sternzeichentabelle: */
char zodiac [12] [11] = { "STEINBOCK" , "WASSERMANN", "FISCHE",
"WIDDER", "STIER", "ZWILLINGE",
"KREBS", "LÖWE", "JUNGFRAU",
"WAAGE", "SKORPION", "SCHÜTZE"};
/* Tabelle der Tage, die bis zu einem bestimmten Monat vergangen sind: */
int monsum [13] = { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
/* Nummer des Anfangstages (im Intervall 1 - 365) eines Sternzeichens: */
int start [12] = { 1, 31, 62, 90, 121, 151, 183, 214, 246, 277, 307, 337 };
/* Nummer des Endtages (im Intervall 1 - 365) eines Sternzeichens
(hier nicht noetig): */
int end [12] = { 30, 61, 89, 120, 150, 182, 213, 245, 276, 306, 336, 365 };
int i;
int day; /* Geburtstag */
int mon; /* Geburtsmonat*/
int tnum; /* Geburtstag und Geburtsmonat umgerechnet in den
entsprechenden Tag des Tierkreisjahres (1-365) */
printf("\n\nTag und Monat des Geburtsdatums eingeben (tt mm): ");
scanf("%d %d", &day, &mon);
/* Datum umrechnen in Anzahl der vergangenen Tage seit dem 22.12.,
dem ersten Zeichen im Turnus (STEINBOCK) */
if (monsum[mon] + day + 10 > 365)
tnum = monsum[mon] + day + 10 - 365;
else
tnum = monsum[mon] + day + 10;
i = 0;
while (tnum > start[i]) i++;
printf("%d %d Ihr Sternzeichen ist %s\n", tnum,i-1,zodiac[i-1]);
return(0);
}
|
|
|