サーチ…


ストリームから読み取られた文字の分類

#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マクロの値として表現可能であると予想しています。
  • *pchar型であるため、上記の表現と一致するように変換する必要があります。
  • char型は、 signed charまたはunsigned charいずれかと同等に定義されています。
  • charunsigned char charと同じ場合、 char型の可能な値はすべてunsigned charとして表現できるので、問題はありません。
  • charsigned char charと同等の場合、文字分類関数に渡す前にunsigned charに変換する必要があります。そして、この変換のために文字の価値は変わるかもしれませんが、これはまさにこれらの関数が期待するものです。
  • 文字分類関数の戻り値は、ゼロ( false意味する)と非ゼロ( true意味する)の間でのみ区別されます。出現回数をカウントするには、この値を1または0に変換する必要があります。これは、二重否定によって行われます!!

前書き

ヘッダーctype.hは標準Cライブラリの一部です。文字の分類と変換のための関数を提供します。

これらの機能のすべてが一つのパラメータ、取るintはunsigned charとして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. */

2つの変換関数があります。これらは、接頭辞 '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);

以下の情報は、元の127文字のASCIIセットが各分類タイプ関数によってどのように考慮されているかをマッピングするcplusplus.comから引用されています(•は、その文字がその関数でゼロ以外の値を返すことを示します)

ASCII値文字 iscntrl isblank isspace イサッパイローダーイソアルファ isdigit isxdigit イスラム ispunct アイソグラフ isprint
0x00 .. 0x08 NUL、(他の制御コード)
0x09 タブ( '\ 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