我有一个文本文件,其中可以包含中文,日文,韩文(CJK)和英文字符的混合。我必须验证文件的英文字符。只有当一行以'$'字符开头时,才允许该文件包含CJK字符,该字符代表我的文本文件中的注释。通过网络搜索,我发现我可以使用fgetws()
和wchar_t
类型来读取宽字符。
Q1)但我想知道如何将CJK字符存储在我的文本文件中 - 字节顺序等等。
Q2)如何循环使用CJK字符。由于Unicode字符可以有1到6个字节,所以我不能使用i ++。
任何帮助都将不胜感激。
非常感谢。
答案 0 :(得分:1)
您需要将UTF-8文件作为一系列UTF-32代码点读取。例如:
std::shared_ptr<FILE> f(fopen(filename, "r"), fclose);
uint32_t c = 0;
while (utf8_read(f.get(), c))
{
if (is_english_char(c))
...
else if (is_cjk_char(c))
...
else
...
}
utf8_read
有签名的地方:
bool utf8_read(FILE *f, uint32_t &c);
现在,utf8_read
可能会读取1-4个字节,具体取决于第一个字节的值。请参阅http://en.wikipedia.org/wiki/UTF-8,google了解算法或使用您已经可以使用的库函数。
使用UTF-32代码点,您现在可以检查范围。对于英语,您可以检查它是否为ASCII(c < 0x7F
)或者是否为Latin
字符(包括对来自例如法语的导入单词的重音字符的支持)。您可能还想排除不可打印的控制字符(例如0x01
)。
对于Latin
和/或CJK
字符检查,您可以检查字符是否在给定的代码块中(有关代码点范围,请参阅http://www.unicode.org/Public/UNIDATA/Blocks.txt)。这是最简单的方法。
如果您正在使用具有编写脚本检测功能的Unicode支持的库(例如glib库),则可以使用脚本类型来检测字符。或者,您可以从http://www.unicode.org/Public/UNIDATA/Scripts.txt获取数据:
Name : Code : Language(s)
=========:===========:========================================================
Common : Zyyy : general punctuation / symbol characters
Latin : Latn : Latin languages (English, German, French, Spanish, ...)
Han : Hans/Hant : Chinese characters (Chinese, Japanese)
Hiragana : Hira : Japanese
Katakana : Kana : Japanese
Hangul : Hang : Korean
注意:脚本代码来自http://www.iana.org/assignments/language-subtag-registry(Type == 'script'
)。
答案 1 :(得分:0)
您需要了解UTF-8并使用一些UTF8处理库(或您自己的代码)。仅供参考,Glib(来自GTK)具有UTF-8处理功能,能够处理可变长度的UTF-8字符和字符串。字符串。还有其他UTF-8库,例如iconv - 在GNU libc中 - 和ICU以及许多其他人。
UTF-8确定了多字节UTF8字符的字节顺序和内容,例如中国人。
答案 2 :(得分:0)
我正在粘贴一个示例程序来说明wchar_t处理。希望它可以帮到某人。
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#define BUFLEN 1024
int main() {
wchar_t *wmessage=L"Lets- beginめん(下) 震災後、保存-食で-脚光-(経済ナビゲーター)-lets- end";
wchar_t warray[BUFLEN + 1];
wchar_t a = L'z';
int i=0;
FILE *fp;
wchar_t *token = L"-";
wchar_t *state;
wchar_t *ptr;
setlocale(LC_ALL, "");
/* FIle in current dirrctory containing CJK chars */
fp = fopen("input", "r");
if (fp == NULL) {
printf("%s\n", "Cannot open file!!!");
return (-1);
}
fgetws(warray, BUFLEN, fp);
wprintf(L"\n *********************START reading from file*******************************\n");
wprintf(L"%ls\n",warray);
wprintf(L"\n*********************END reading from file*******************************\n");
fclose(fp);
wprintf(L"printing character %lc = <0x%x>\n", a, a);
wprintf(L"\n*********************START Checking string for Japanese*******************************\n");
for(i=0;wmessage[i] != '\0';i++) {
if (wmessage[i] > 0x7F) {
wprintf(L"\n This is non-ASCII <0x%x> <%lc>", wmessage[i], wmessage[i]);
} else {
wprintf(L"\n This is ASCII <0x%x> <%lc>", wmessage[i], wmessage[i]);
}
}
wprintf(L"\n*********************END Checking string for Japanese*******************************\n");
wprintf(L"\n*********************START Tokenizing******************************\n");
state = wcstok(warray, token, &ptr);
while (state != NULL) {
wprintf(L"\n %ls", state);
state = wcstok(NULL, token, &ptr);
}
wprintf(L"\n*********************END Tokenizing******************************\n");
return 0;
}