Поиск…


Классификация символов, считанных из потока

#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. */
C99
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)


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow