C Language
- классификация символов и конверсия
Поиск…
Классификация символов, считанных из потока
#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;
}
Функция classify
считывает символы из потока и подсчитывает количество пробелов, буквенно-цифровых символов и знаков препинания. Это позволяет избежать нескольких подводных камней.
- При чтении символа из потока результат сохраняется как
int
, так как в противном случае между чтениемEOF
(маркером конца файла) и символом, имеющим один и тот же битовый шаблон, была бы двусмысленность. - Функции классификации символов (например,
isspace
) ожидают, что их аргумент будет либо представлен какunsigned char
, либо значение макросаEOF
. Поскольку это именно то, что возвращаетfgetc
, здесь нет необходимости в преобразовании. - Возвращаемое значение функций классификации символов различает только ноль (значение
false
) и ненулевой (что означаетtrue
). Для подсчета количества вхождений это значение нужно преобразовать в 1 или 0, что делается двойным отрицанием!!
,
Классификация символов из строки
#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;
}
Функция classify
проверяет все символы из строки и подсчитывает количество пробелов, буквенно-цифровых символов и знаков препинания. Это позволяет избежать нескольких подводных камней.
- Функции классификации символов (например,
isspace
) ожидают, что их аргумент будет либо представлен какunsigned char
, либо значение макросаEOF
. - Выражение
*p
имеет типchar
и поэтому должно быть преобразовано в соответствии с указанной выше формулировкой. - Тип
char
определяется как эквивалентный знакуsigned char
илиunsigned char
. - Когда
char
эквивалентенunsigned char
, нет никакой проблемы, так как все возможные значения типаchar
представляются какunsigned char
. - Когда
char
эквивалентенsigned char
, он должен быть преобразован вunsigned char
прежде чем передавать его в функции классификации символов. И хотя значение символа может измениться из-за этого преобразования, это именно то, что ожидают эти функции. - Возвращаемое значение функций классификации символов различает только ноль (значение
false
) и ненулевой (что означаетtrue
). Для подсчета количества вхождений это значение нужно преобразовать в 1 или 0, что делается двойным отрицанием!!
,
Вступление
Заголовок ctype.h
является частью стандартной библиотеки C. Он предоставляет функции для классификации и преобразования символов.
Все эти функции принимают один параметр, int
который должен быть либо EOF, либо представлен как символ без знака.
Имена классификационных функций имеют префикс «is». Каждый возвращает целое ненулевое значение (TRUE), если переданный ему символ удовлетворяет соответствующему условию. Если условие не выполняется, функция возвращает нулевое значение (FALSE).
Эти классифицирующие функции работают, как показано, принимая значение по умолчанию для языка C:
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. */
Существует две функции преобразования. Они называются с использованием префикса 'to'. Эти функции имеют тот же аргумент, что и выше. Однако возвращаемое значение не является простым нулем или ненулевым, но переданный аргумент каким-то образом изменился.
Эти функции преобразования функционируют, как показано, при условии, что язык по умолчанию C:
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);
Ниже приведена приведенная ниже информация cflusplus.com о том, как исходный 127-символьный набор ASCII рассматривается каждой из классифицирующих функций типа (a • указывает, что функция возвращает ненулевое значение для этого символа)
Значения ASCII | персонажи | iscntrl | ISBLANK | isspace | ISUPPER | ISLOWER | ISALPHA | isdigit | isxdigit | isalnum | ispunct | isgraph | isprint |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x00 .. 0x08 | NUL (другие управляющие коды) | • | |||||||||||
0x09 | tab ('\ t') | • | • | • | |||||||||
0x0A .. 0x0D | (управляющие коды белого пространства: '\ f', '\ v', '\ n', '\ r') | • | • | ||||||||||
0x0E .. 0x1F | (другие управляющие коды) | • | |||||||||||
0x20 | пространство (' ') | • | • | • | |||||||||
0x21 .. 0x2F | ! "# $% & '() * +, -. / | • | • | • | |||||||||
0x30 .. 0x39 | 0123456789 | • | • | • | • | • | |||||||
0x3a .. 0x40 | :;? <=> @ | • | • | • | |||||||||
0x41 .. 0x46 | ABCDEF | • | • | • | • | • | • | ||||||
0x47 .. 0x5A | GHIJKLMNOPQRSTUVWXYZ | • | • | • | • | • | |||||||
0x5B .. 0x60 | [] ^ _ ` | • | • | • | |||||||||
0x61 .. 0x66 | ABCDEF | • | • | • | • | • | • | ||||||
0x67 .. 0x7A | ghijklmnopqrstuvwxyz | • | • | • | • | • | |||||||
0x7B .. 0x7E | {} ~ Бар | • | • | • | |||||||||
0x7F | (DEL) | • |