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
と同じ場合、char
型の可能な値はすべてunsigned char
として表現できるので、問題はありません。 -
char
がsigned 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