C Language
- karakterclassificatie & conversie
Zoeken…
Classificeren van karakters gelezen uit een stream
#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;
}
De classify
leest tekens uit een stream en telt het aantal spaties, alfanumerieke tekens en leestekens. Het vermijdt verschillende valkuilen.
- Bij het lezen van een personage uit een stream, wordt het resultaat opgeslagen als een
int
, omdat er anders een dubbelzinnigheid zou bestaan tussen het lezen vanEOF
(de einde-van-bestandsmarkering) en een personage met hetzelfde bitpatroon. - De functies voor
isspace
(bijvoorbeeldisspace
) verwachten dat hun argument kan worden weergegeven als eenunsigned char
, of de waarde van deEOF
macro . Aangezien dit precies is wat defgetc
retourneert, is hier geen conversie nodig. - De geretourneerde waarde van de functies voor tekenclassificatie maakt alleen onderscheid tussen nul (betekent
false
) en niet-nul (betekenttrue
). Voor het tellen van het aantal keren dat deze voorkomt, moet deze waarde worden omgezet in een 1 of 0, wat wordt gedaan door de dubbele ontkenning,!!
.
Tekens uit een string classificeren
#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;
}
De functie classify
onderzoekt alle tekens van een tekenreeks en telt het aantal spaties, alfanumerieke tekens en leestekens. Het vermijdt verschillende valkuilen.
- De functies voor
isspace
(bijvoorbeeldisspace
) verwachten dat hun argument kan worden weergegeven als eenunsigned char
, of de waarde van deEOF
macro . - De uitdrukking
*p
is van het typechar
en moet daarom worden omgezet in overeenstemming met de bovenstaande bewoording. - Het
char
type is gedefinieerd als gelijk aan ofwelsigned char
ofunsigned char
. - Als
char
gelijk staat aanunsigned char
, is er geen probleem, aangezien elke mogelijke waarde van hetchar
type kan worden weergegeven alsunsigned char
. - Wanneer
char
gelijk is aansigned char
, moet het worden omgezet inunsigned char
voordat het wordt doorgegeven aan de karakterclassificatiefuncties. En hoewel de waarde van het personage door deze conversie kan veranderen, is dit precies wat deze functies verwachten. - De geretourneerde waarde van de functies voor tekenclassificatie maakt alleen onderscheid tussen nul (betekent
false
) en niet-nul (betekenttrue
). Voor het tellen van het aantal keren dat deze voorkomt, moet deze waarde worden omgezet in een 1 of 0, wat wordt gedaan door de dubbele ontkenning,!!
.
Invoering
De koptekst ctype.h
maakt deel uit van de standaard C-bibliotheek. Het biedt functies voor het classificeren en converteren van tekens.
Al deze functies hebben één parameter nodig, een int
die EOF moet zijn of moet kunnen worden weergegeven als een niet-ondertekend teken.
De namen van de classificatiefuncties worden voorafgegaan door 'is'. Elk retourneert een geheel getal niet-nulwaarde (WAAR) als het doorgegeven teken voldoet aan de gerelateerde voorwaarde. Als niet aan de voorwaarde wordt voldaan, retourneert de functie een nulwaarde (FALSE).
Deze classificatiefuncties werken zoals weergegeven, uitgaande van de standaard C-landinstelling:
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. */
Er zijn twee conversiefuncties. Deze worden genoemd met het voorvoegsel 'to'. Deze functies hebben hetzelfde argument als die hierboven. De retourwaarde is echter geen eenvoudige nul of niet-nul, maar het doorgegeven argument is op een of andere manier gewijzigd.
Deze conversiefuncties werken zoals weergegeven, uitgaande van de standaard C-landinstelling:
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);
De onderstaande informatie is geciteerd uit cplusplus.com die in kaart brengt hoe de oorspronkelijke ASCII-set van 127 tekens wordt beschouwd door elk van de classificatietypefuncties (een • geeft aan dat de functie niet-nul retourneert voor dat teken)
ASCII-waarden | tekens | iscntrl | is leeg | isspace | isupper | is lager | isAlpha | isdigit | isxdigit | isalnum | ispunct | isgraph | isprint |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x00 .. 0x08 | NUL, (andere controle codes) | • | |||||||||||
0x09 | tabblad ('\ t') | • | • | • | |||||||||
0x0A .. 0x0D | (white-space controle codes: '\ f', '\ v', '\ n', '\ r') | • | • | ||||||||||
0x0E .. 0x1F | (andere controlecodes) | • | |||||||||||
0x20 | ruimte (' ') | • | • | • | |||||||||
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) | • |