|
> # 以下は参考までに。私の結論が誤りである可能性もあるし。
> #
> # 私がVCでやったときには、_ismbblead(),_ismbbtrail()等で判定しようとしましたが、
> # 文字列の一番先頭から判定を始めないと完全な判定は不可能という結論に到達しました。
VC でやったということは、Shift JIS ですね。
文字列 s の n バイト目が、シングルバイト文字か、ダブルバイト文字の第1
バイトか第2バイトかは、そこからある程度さかのぼるだけで判定できます。
もちろん、"ラリルレロ" のように先頭までさかのぼらないとだめな場合も
ありますが。
#include <stdio.h>
#define isFirst(c) (((unsigned)(c) ^ 0x20) - 0xA1 < 60)
#define isSecond(c) ((c) >= 0x40 && (c) != 0x7F && (c) <= 0xFc)
/* type() returns 0:single byte, 1:first byte, 2:second byte */
int type(const char *s, int n)
{
int i = n, t = 0; unsigned char c;
while (i > 0 && (c = s[i], isSecond(c)) && (c = s[i-1], isFirst(c)))
--i;
/* printf("i=%d: ", i); // i または i-1 まで見に行った */
do {
t = (t == 1) ? 2 : (c = s[i], isFirst(c));
} while (++i <= n);
return t;
}
int main(void)
{
char s[1024]; int i;
while (fgets(s, sizeof s, stdin))
for (i = 0; s[i]; i++)
printf("s[%d] = %02x: %d\n", i, s[i] & 0xFF, type(s, i));
return 0;
}
|