C言語で、ひらがなorカタカナor全角英数字を判別する方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
山本さん太郎
記事: 5
登録日時: 10年前

C言語で、ひらがなorカタカナor全角英数字を判別する方法

#1

投稿記事 by 山本さん太郎 » 10年前

win  Visual Studio
C言語で、ひらがなorカタカナor全角英数字を判別する方法を教えて頂けないでしょうか。
現在、char *a;に、カタカナ or ひらがな  or 全角英数字が入っています。
これを判別したいのですが、2バイト文字ですのどうやって判別していいか分からず困っております。
よろしくお願い致します。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法

#2

投稿記事 by みけCAT » 10年前

とりあえず文字を列挙してみましたが、Shift_JISの場合「ね」や「村」がカタカナと誤判定されてしまいました。
難しいですね。

コード:

#include <stdio.h>
#include <string.h>

#define KATAKANA 1
#define HIRAGANA 2
#define ZENKAKUEISUUZI 4

int hanbetu(const char* q) {
	static const char* katakana[] = {
		"ア", "イ", "ウ", "エ", "オ",
		"カ", "キ", "ク", "ケ", "コ",
		"サ", "シ", "ス", "セ", "ソ",
		"タ", "チ", "ツ", "テ", "ト",
		"ナ", "ニ", "ヌ", "ネ", "ノ",
		"ハ", "ヒ", "フ", "ヘ", "ホ",
		"マ", "ミ", "ム", "メ", "モ",
		"ヤ",       "ユ",       "ヨ",
		"ラ", "リ", "ル", "レ", "ロ",
		"ワ", "ヰ",       "ヱ", "ヲ", "ン",
		"ガ", "ギ", "グ", "ゲ", "ゴ",
		"ザ", "ジ", "ズ", "ゼ", "ゾ",
		"ダ", "ヂ", "ヅ", "デ", "ド",
		"バ", "ビ", "ブ", "ベ", "ボ",
		"パ", "ピ", "プ", "ペ", "ポ",
		"ァ", "ィ", "ゥ", "ェ", "ォ",
		"ッ", "ヵ", "ヮ",
		"ア", "イ", "ウ", "エ", "オ",
		"カ", "キ", "ク", "ケ", "コ",
		"サ", "シ", "ス", "セ", "ソ",
		"タ", "チ", "ツ", "テ", "ト",
		"ナ", "ニ", "ヌ", "ネ", "ノ",
		"ハ", "ヒ", "フ", "ヘ", "ホ",
		"マ", "ミ", "ム", "メ", "モ",
		"ヤ",      "ユ",      "ヨ",
		"ラ", "リ", "ル", "レ", "ロ",
		"ワ", "イ",      "エ", "ヲ", "ン",
		NULL
	};
	static const char* hiragana[] = {
		"あ", "い", "う", "え", "お",
		"か", "き", "く", "け", "こ",
		"さ", "し", "す", "せ", "そ",
		"た", "ち", "つ", "て", "と",
		"な", "に", "ぬ", "ね", "の",
		"は", "ひ", "ふ", "へ", "ほ",
		"ま", "み", "む", "め", "も",
		"や",       "ゆ",       "よ",
		"ら", "り", "る", "れ", "ろ",
		"わ", "ゐ",       "ゑ", "を", "ん",
		"が", "ぎ", "ぐ", "げ", "ご",
		"ざ", "じ", "ず", "ぜ", "ぞ",
		"だ", "ぢ", "づ", "で", "ど",
		"ば", "び", "ぶ", "べ", "ぼ",
		"ぱ", "ぴ", "ぷ", "ぺ", "ぽ",
		"ぁ", "ぃ", "ぅ", "ぇ", "ぉ",
		"っ", NULL
	};
	static const char* zenkakueisuuzi[] = {
		"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
		"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
		"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
		"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
		"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL
	};
	int res = 0;
	const char **p;
	for (p = katakana; *p != NULL; p++) {
		if (strstr(q, *p) != NULL) {
			res |= KATAKANA;
			break;
		}
	}
	for (p = hiragana; *p != NULL; p++) {
		if (strstr(q, *p) != NULL) {
			res |= HIRAGANA;
			break;
		}
	}
	for (p = zenkakueisuuzi; *p != NULL; p++) {
		if (strstr(q, *p) != NULL) {
			res |= ZENKAKUEISUUZI;
			break;
		}
	}
	return res;
}

int main(void) {
	char input[128];
	char *a;
	int res;
	if (scanf("%127s", input) != 1) return 1;
	a = input;
	res = hanbetu(a);
	if (res & KATAKANA) puts("カタカナ");
	if (res & HIRAGANA) puts("ひらがな");
	if (res & ZENKAKUEISUUZI) puts("全角英数字");
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

山本さん太郎
記事: 5
登録日時: 10年前

Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法

#3

投稿記事 by 山本さん太郎 » 10年前

ありがとうございます!
班別したい文字列は全てひらがな、カタカナ、全角英数字のみで構成されているので、
1文字だけ例外が起きても他の文字で班別できるので大丈夫そうです!

かずま

Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法

#4

投稿記事 by かずま » 10年前

コード:

#include <stdio.h>

int isleading(unsigned char c) { return (c ^ 0x20) - 0xa1u < 60; }

int main(void)
{
    char buf[1024], *p;
    unsigned char c1, c2;
    while (fgets(buf, sizeof buf, stdin))
        for (p = buf; c1 = *p; p++)
            if (isleading(c1)) {
                c2 = *++p;
                if (c1 == 0x82 && c2 >= 0x9f && c2 <= 0xf1)
                    printf("%c%c: 平仮名\n", c1, c2);
                else if (c1 == 0x83 && c2 >= 0x40 && c2 <= 0x90)
                    printf("%c%c: 片仮名\n", c1, c2);
                else if (c1 == 0x82 && c2 >= 0x4f && c2 <= 0x9a)
                    printf("%c%c: 英数字\n", c1, c2);
                else
                    printf("%c%c: その他\n", c1, c2);
            }
            else
                printf("%c: 半角文字\n", c1);
    return 0;
}
英数字のところは、判定をさぼっています。
本当は、数字、大文字、小文字という範囲でチェックした方がよいでしょう。

分からないところがありますか?
他のやり方もありますが、興味ありますか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法

#5

投稿記事 by みけCAT » 10年前

かずま さんが書きました:

コード:

#include <stdio.h>

int isleading(unsigned char c) { return (c ^ 0x20) - 0xa1u < 60; }

int main(void)
{
    char buf[1024], *p;
    unsigned char c1, c2;
    while (fgets(buf, sizeof buf, stdin))
        for (p = buf; c1 = *p; p++)
            if (isleading(c1)) {
                c2 = *++p;
                if (c1 == 0x82 && c2 >= 0x9f && c2 <= 0xf1)
                    printf("%c%c: 平仮名\n", c1, c2);
                else if (c1 == 0x83 && c2 >= 0x40 && c2 <= 0x90)
                    printf("%c%c: 片仮名\n", c1, c2);
                else if (c1 == 0x82 && c2 >= 0x4f && c2 <= 0x9a)
                    printf("%c%c: 英数字\n", c1, c2);
                else
                    printf("%c%c: その他\n", c1, c2);
            }
            else
                printf("%c: 半角文字\n", c1);
    return 0;
}
実行して確認してはいませんが、このコードだと半角カタカナを片仮名と判定してくれないのではないでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法

#6

投稿記事 by みけCAT » 10年前

山本さん太郎 さんが書きました:2バイト文字ですのどうやって判別していいか分からず困っております。
「2バイト文字」ということは、文字コードはShift_JISですか?それともUTF-16ですか?その他ですか?
ある文字コードに依存した判定方法でもいいですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法

#7

投稿記事 by みけCAT » 10年前

山本さん太郎 さんが書きました:班別したい文字列は全てひらがな、カタカナ、全角英数字のみで構成されているので
1種類のみという制約は無いのですね?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

山本さん太郎
記事: 5
登録日時: 10年前

Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法

#8

投稿記事 by 山本さん太郎 » 10年前

みけCAT さんが書きました:とりあえず文字を列挙してみましたが、Shift_JISの場合「ね」や「村」がカタカナと誤判定されてしまいました。
難しいですね。

コード:

#include <stdio.h>
#include <string.h>

#define KATAKANA 1
#define HIRAGANA 2
#define ZENKAKUEISUUZI 4

int hanbetu(const char* q) {
	static const char* katakana[] = {
		"ア", "イ", "ウ", "エ", "オ",
		"カ", "キ", "ク", "ケ", "コ",
		"サ", "シ", "ス", "セ", "ソ",
		"タ", "チ", "ツ", "テ", "ト",
		"ナ", "ニ", "ヌ", "ネ", "ノ",
		"ハ", "ヒ", "フ", "ヘ", "ホ",
		"マ", "ミ", "ム", "メ", "モ",
		"ヤ",       "ユ",       "ヨ",
		"ラ", "リ", "ル", "レ", "ロ",
		"ワ", "ヰ",       "ヱ", "ヲ", "ン",
		"ガ", "ギ", "グ", "ゲ", "ゴ",
		"ザ", "ジ", "ズ", "ゼ", "ゾ",
		"ダ", "ヂ", "ヅ", "デ", "ド",
		"バ", "ビ", "ブ", "ベ", "ボ",
		"パ", "ピ", "プ", "ペ", "ポ",
		"ァ", "ィ", "ゥ", "ェ", "ォ",
		"ッ", "ヵ", "ヮ",
		"ア", "イ", "ウ", "エ", "オ",
		"カ", "キ", "ク", "ケ", "コ",
		"サ", "シ", "ス", "セ", "ソ",
		"タ", "チ", "ツ", "テ", "ト",
		"ナ", "ニ", "ヌ", "ネ", "ノ",
		"ハ", "ヒ", "フ", "ヘ", "ホ",
		"マ", "ミ", "ム", "メ", "モ",
		"ヤ",      "ユ",      "ヨ",
		"ラ", "リ", "ル", "レ", "ロ",
		"ワ", "イ",      "エ", "ヲ", "ン",
		NULL
	};
	static const char* hiragana[] = {
		"あ", "い", "う", "え", "お",
		"か", "き", "く", "け", "こ",
		"さ", "し", "す", "せ", "そ",
		"た", "ち", "つ", "て", "と",
		"な", "に", "ぬ", "ね", "の",
		"は", "ひ", "ふ", "へ", "ほ",
		"ま", "み", "む", "め", "も",
		"や",       "ゆ",       "よ",
		"ら", "り", "る", "れ", "ろ",
		"わ", "ゐ",       "ゑ", "を", "ん",
		"が", "ぎ", "ぐ", "げ", "ご",
		"ざ", "じ", "ず", "ぜ", "ぞ",
		"だ", "ぢ", "づ", "で", "ど",
		"ば", "び", "ぶ", "べ", "ぼ",
		"ぱ", "ぴ", "ぷ", "ぺ", "ぽ",
		"ぁ", "ぃ", "ぅ", "ぇ", "ぉ",
		"っ", NULL
	};
	static const char* zenkakueisuuzi[] = {
		"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
		"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
		"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
		"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
		"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL
	};
	int res = 0;
	const char **p;
	for (p = katakana; *p != NULL; p++) {
		if (strstr(q, *p) != NULL) {
			res |= KATAKANA;
			break;
		}
	}
	for (p = hiragana; *p != NULL; p++) {
		if (strstr(q, *p) != NULL) {
			res |= HIRAGANA;
			break;
		}
	}
	for (p = zenkakueisuuzi; *p != NULL; p++) {
		if (strstr(q, *p) != NULL) {
			res |= ZENKAKUEISUUZI;
			break;
		}
	}
	return res;
}

int main(void) {
	char input[128];
	char *a;
	int res;
	if (scanf("%127s", input) != 1) return 1;
	a = input;
	res = hanbetu(a);
	if (res & KATAKANA) puts("カタカナ");
	if (res & HIRAGANA) puts("ひらがな");
	if (res & ZENKAKUEISUUZI) puts("全角英数字");
	return 0;
}
文字コードはShift_JISで、1種類のみという制約は無いのです。
上記の記述方を参考にさせていただきましたが、今のところ何の問題もなく動作しております。

かずま

Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法

#9

投稿記事 by かずま » 10年前

みけCAT さんが書きました: 実行して確認してはいませんが、このコードだと半角カタカナを片仮名と判定してくれないのではないでしょうか?
最初の質問に
山本さん太郎 さんが書きました: これを判別したいのですが、2バイト文字ですのどうやって判別していいか分からず困っております。
とあったので、1バイトの片仮名は無視しました。それを判別したければ、
isleading(c1) で 1バイト文字を 2バイト文字と分けた後、次のようにしてください。

コード:

    if (c1 >= 0xa6 && c1 <= 0xdf)
		printf("%c: 半角片仮名\n", c1);
	else 
		printf("%c: その他\n", c1);
Shift JIS で、「ね」は 82 cb、「村」は 91 ba、「ヒ」は cb、「コ」は ab です。

したがって、strstr("ね", "ヒ") は strstr("\x82\xcb", "\xcb") と、
strstr("村", "コ") は strstr("\x91\xba", "\xba") と同じなので、
どちらも NULL を返しません。

Shift JIS の文字列の操作に strstr を使うことは間違いです。
UTF-8 なら、strstr で文字単位の判別が可能です。

かずま

Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法

#10

投稿記事 by かずま » 10年前

かずま さんが書きました: Shift JIS で、「ね」は 82 cb、「村」は 91 ba、「ヒ」は cb、「コ」は ab です。
「コ」は ab ではなく ba ですね。

他にも、「モジ」は 83 82 83 57、「c」は 82 83 ですから、
strstr("モジ", "c") が NULL を返さず、「モジ」が全角英数字に
なってしまいます。
山本さん太郎 さんが書きました: 上記の記述方を参考にさせていただきましたが、今のところ何の問題もなく動作しております。
今のところ何の問題もなく動作していても、いつ間違った判別をしてしまうか分かりません。

閉鎖

“C言語何でも質問掲示板” へ戻る