C Language
- Klassifizierung und Konvertierung von Zeichen
Suche…
Klassifizieren von Zeichen, die aus einem Stream gelesen wurden
#include <ctype.h>
#include <stdio.h>
typedef struct {
size_t space;
size_t alnum;
size_t punct;
} chartypes;
chartypes classify(FILE *f) {
chartypes types = { 0, 0, 0 };
int ch;
while ((ch = fgetc(f)) != EOF) {
types.space += !!isspace(ch);
types.alnum += !!isalnum(ch);
types.punct += !!ispunct(ch);
}
return types;
}
Die classify
liest Zeichen aus einem Stream und zählt die Anzahl der Leerzeichen, alphanumerischen Zeichen und Satzzeichen. Es vermeidet mehrere Fallstricke.
- Beim Lesen eines Zeichens aus einem Stream wird das Ergebnis als
int
gespeichert, da andernfalls das Lesen vonEOF
(Dateiendemarker) und ein Zeichen, das dasselbe Bitmuster aufweist, nicht eindeutig sind. - Die Zeichenklassifizierungsfunktionen (z. B.
isspace
) erwarten, dass ihr Argument entweder alsunsigned char
Zeichen oder als Wert desEOF
Makros darstellbar ist . Da dies genau das ist, was diefgetc
zurückgibt, ist hier keine Konvertierung erforderlich. - Der Rückgabewert der Zeichenklassifizierungsfunktionen unterscheidet nur zwischen Null (Bedeutung
false
) und Nicht-Null (Bedeutungtrue
). Um die Anzahl der Vorkommen zu zählen, muss dieser Wert in eine 1 oder 0 umgewandelt werden. Dies geschieht durch die doppelte Negation.!!
.
Zeichen aus einer Zeichenfolge klassifizieren
#include <ctype.h>
#include <stddef.h>
typedef struct {
size_t space;
size_t alnum;
size_t punct;
} chartypes;
chartypes classify(const char *s) {
chartypes types = { 0, 0, 0 };
const char *p;
for (p= s; p != '\0'; p++) {
types.space += !!isspace((unsigned char)*p);
types.alnum += !!isalnum((unsigned char)*p);
types.punct += !!ispunct((unsigned char)*p);
}
return types;
}
Die classify
überprüft alle Zeichen einer Zeichenfolge und zählt die Anzahl der Leerzeichen, alphanumerischen Zeichen und Satzzeichen. Es vermeidet mehrere Fallstricke.
- Die Zeichenklassifizierungsfunktionen (z. B.
isspace
) erwarten, dass ihr Argument entweder alsunsigned char
Zeichen oder als Wert desEOF
Makros darstellbar ist . - Der Ausdruck
*p
ist vom Typchar
und muss daher entsprechend dem obigen Wortlaut konvertiert werden. - Der
char
Typ ist definiert als entwedersigned char
oderunsigned char
. - Wenn
char
einemunsigned char
, besteht kein Problem, da jeder mögliche Wert des Typs "char
alsunsigned char
. - Wenn
char
äquivalent zusigned char
, muss es inunsigned char
umgewandelt werden, bevor es an die Zeichenklassifizierungsfunktionen übergeben wird. Und obwohl sich der Wert des Zeichens aufgrund dieser Konvertierung ändern kann, erwarten genau diese Funktionen diese Funktion. - Der Rückgabewert der Zeichenklassifizierungsfunktionen unterscheidet nur zwischen Null (Bedeutung
false
) und Nicht-Null (Bedeutungtrue
). Um die Anzahl der Vorkommen zu zählen, muss dieser Wert in eine 1 oder 0 umgewandelt werden. Dies geschieht durch die doppelte Negation.!!
.
Einführung
Der Header ctype.h
ist Teil der Standard-C-Bibliothek. Es bietet Funktionen zum Klassifizieren und Konvertieren von Zeichen.
Alle diese Funktionen benötigen einen Parameter, ein int
, das entweder EOF sein muss oder als vorzeichenloses Zeichen dargestellt werden kann.
Die Namen der klassifizierenden Funktionen sind mit 'is' versehen. Jeder gibt einen ganzzahligen Wert ungleich Null (TRUE) zurück, wenn das übergebene Zeichen die zugehörige Bedingung erfüllt. Wenn die Bedingung nicht erfüllt ist, gibt die Funktion einen Nullwert zurück (FALSE).
Diese Klassifizierungsfunktionen funktionieren wie gezeigt, vorausgesetzt, das Standardgebietsschema C wird verwendet:
int a;
int c = 'A';
a = isalpha(c); /* Checks if c is alphabetic (A-Z, a-z), returns non-zero here. */
a = isalnum(c); /* Checks if c is alphanumeric (A-Z, a-z, 0-9), returns non-zero here. */
a = iscntrl(c); /* Checks is c is a control character (0x00-0x1F, 0x7F), returns zero here. */
a = isdigit(c); /* Checks if c is a digit (0-9), returns zero here. */
a = isgraph(c); /* Checks if c has a graphical representation (any printing character except space), returns non-zero here. */
a = islower(c); /* Checks if c is a lower-case letter (a-z), returns zero here. */
a = isprint(c); /* Checks if c is any printable character (including space), returns non-zero here. */
a = isupper(c); /* Checks if c is a upper-case letter (a-z), returns zero here. */
a = ispunct(c); /* Checks if c is a punctuation character, returns zero here. */
a = isspace(c); /* Checks if c is a white-space character, returns zero here. */
a = isupper(c); /* Checks if c is an upper-case letter (A-Z), returns non-zero here. */
a = isxdigit(c); /* Checks if c is a hexadecimal digit (A-F, a-f, 0-9), returns non-zero here. */
a = isblank(c); /* Checks if c is a blank character (space or tab), returns non-zero here. */
Es gibt zwei Konvertierungsfunktionen. Diese werden mit dem Präfix 'bis' benannt. Für diese Funktionen gelten dieselben Argumente wie oben. Der Rückgabewert ist jedoch keine einfache Null oder Nicht-Null, sondern das übergebene Argument hat sich in gewisser Weise geändert.
Diese Konvertierungsfunktionen funktionieren wie gezeigt, vorausgesetzt, das Standardgebietsschema C wird verwendet:
int a;
int c = 'A';
/* Converts c to a lower-case letter (a-z).
* If conversion is not possible the unchanged value is returned.
* Returns 'a' here.
*/
a = tolower(c);
/* Converts c to an upper-case letter (A-Z).
* If conversion is not possible the unchanged value is returned.
* Returns 'A' here.
*/
a = toupper(c);
Die folgende Information wird aus cplusplus.com-Zitate zitiert, wie der ursprüngliche aus 127 Zeichen bestehende ASCII-Satz von jeder der klassifizierenden Typfunktionen betrachtet wird (a • zeigt an, dass die Funktion für dieses Zeichen nicht Null zurückgibt)
ASCII-Werte | Zeichen | iscntrl | ist leer | isspace | Isupper | ist tiefer | isalpha | isdigit | isxdigit | isalnum | ispunct | isgraph | isprint |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x00 .. 0x08 | NUL, (andere Steuercodes) | • | |||||||||||
0x09 | Tab ('\ t') | • | • | • | |||||||||
0x0A .. 0x0D | (Leerraumkontrollcodes: '\ f', '\ v', '\ n', '\ r') | • | • | ||||||||||
0x0E .. 0x1F | (andere Steuercodes) | • | |||||||||||
0x20 | Platz (' ') | • | • | • | |||||||||
0x21 .. 0x2F | ! "# $% & '() * +, -. / | • | • | • | |||||||||
0x30 .. 0x39 | 0123456789 | • | • | • | • | • | |||||||
0x3a .. 0x40 | :; <=>? @ | • | • | • | |||||||||
0x41 .. 0x46 | ABCDEF | • | • | • | • | • | • | ||||||
0x47 .. 0x5A | GHIJKLMNOPQRSTUVWXYZ | • | • | • | • | • | |||||||
0x5B .. 0x60 | [] ^ _ ` | • | • | • | |||||||||
0x61 .. 0x66 | abcdef | • | • | • | • | • | • | ||||||
0x67 .. 0x7A | ghijklmnopqrstuvwxyz | • | • | • | • | • | |||||||
0x7B .. 0x7E | {} ~ bar | • | • | • | |||||||||
0x7F | (DEL) | • |