win Visual Studio
C言語で、ひらがなorカタカナor全角英数字を判別する方法を教えて頂けないでしょうか。
現在、char *a;に、カタカナ or ひらがな or 全角英数字が入っています。
これを判別したいのですが、2バイト文字ですのどうやって判別していいか分からず困っております。
よろしくお願い致します。
C言語で、ひらがなorカタカナor全角英数字を判別する方法
Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法
とりあえず文字を列挙してみましたが、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で殴ればいい!(死亡フラグ)
Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法
ありがとうございます!
班別したい文字列は全てひらがな、カタカナ、全角英数字のみで構成されているので、
1文字だけ例外が起きても他の文字で班別できるので大丈夫そうです!
班別したい文字列は全てひらがな、カタカナ、全角英数字のみで構成されているので、
1文字だけ例外が起きても他の文字で班別できるので大丈夫そうです!
Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法
#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;
}
本当は、数字、大文字、小文字という範囲でチェックした方がよいでしょう。
分からないところがありますか?
他のやり方もありますが、興味ありますか?
Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法
実行して確認してはいませんが、このコードだと半角カタカナを片仮名と判定してくれないのではないでしょうか?かずま さんが書きました:#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で殴ればいい!(死亡フラグ)
Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法
「2バイト文字」ということは、文字コードはShift_JISですか?それともUTF-16ですか?その他ですか?山本さん太郎 さんが書きました:2バイト文字ですのどうやって判別していいか分からず困っております。
ある文字コードに依存した判定方法でもいいですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法
1種類のみという制約は無いのですね?山本さん太郎 さんが書きました:班別したい文字列は全てひらがな、カタカナ、全角英数字のみで構成されているので
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法
文字コードはShift_JISで、1種類のみという制約は無いのです。みけ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; }
上記の記述方を参考にさせていただきましたが、今のところ何の問題もなく動作しております。
Re: C言語で、ひらがなorカタカナor全角英数字を判別する方法
最初の質問にみけCAT さんが書きました: 実行して確認してはいませんが、このコードだと半角カタカナを片仮名と判定してくれないのではないでしょうか?
とあったので、1バイトの片仮名は無視しました。それを判別したければ、山本さん太郎 さんが書きました: これを判別したいのですが、2バイト文字ですのどうやって判別していいか分からず困っております。
isleading(c1) で 1バイト文字を 2バイト文字と分けた後、次のようにしてください。 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全角英数字を判別する方法
「コ」は ab ではなく ba ですね。かずま さんが書きました: Shift JIS で、「ね」は 82 cb、「村」は 91 ba、「ヒ」は cb、「コ」は ab です。
他にも、「モジ」は 83 82 83 57、「c」は 82 83 ですから、
strstr("モジ", "c") が NULL を返さず、「モジ」が全角英数字に
なってしまいます。
今のところ何の問題もなく動作していても、いつ間違った判別をしてしまうか分かりません。山本さん太郎 さんが書きました: 上記の記述方を参考にさせていただきましたが、今のところ何の問題もなく動作しております。