处理C中的多字节(非ASCII)字符

use*_*838 5 c string file character

我想做我自己的版本的wc(unix过滤器),但我有非ASCII字符的问题.我做了一个文本文件的HEX转储,发现这些字符占用多个字节,所以它们不适合char.有什么方法我怎么能从文件中读取这些字符并像C一样处理它们(所以我可以计算文件中的字符)?我一直在谷歌搜索并找到一些wchar_t类型,但没有任何简单的例子如何将它与文件一起使用.

Joe*_*ams 8

我一直在谷歌搜索并找到一些wchar_t类型,但没有任何简单的例子如何将它与文件一起使用.

很满意.没有任何简单的例子,因为不幸的是,正确的字符集支持并不简单.

旁白:在一个理想的世界中,每个人都会使用UTF-8(一种具有内存效率,健壮且向后兼容ASCII的Unicode编码),标准C库将包括UTF-8编码解码支持,以及答案对这个问题(以及一般的文本处理)将是简单和直接的.

问题" 什么是C的最佳unicode库? " 的答案是使用ICU库.您可能希望查看ustdio.h,因为它有一个u_fgetc函数,并且为您的程序添加Unicode支持可能只需输入u_几次就可以了.

此外,如果您可以节省几分钟的时间阅读,那么您可能需要阅读绝对最低限度的每个软件开发人员绝对必须知道的 Joel On Software的Unicode和字符集(No Excuses!).

我个人从来没有使用过ICU,但我可能会从现在开始:-)


caf*_*caf 6

如果您想编写一个标准 C 版本的wc实用程序,在运行时尊重当前的语言设置,那么您确实可以使用wchar_tstdio 函数的版本。在程序启动时,您应该调用setlocale()

setlocale(LC_CTYPE, "");
Run Code Online (Sandbox Code Playgroud)

这将导致宽字符函数使用环境定义的适当字符集 - 例如。在类 Unix 系统上,LANG环境变量。例如,这意味着如果您的LANG变量设置为UTF8区域设置,则宽字符函数将以 UTF8 处理输入和输出。(这就是 POSIXwc实用程序指定的工作方式)。

然后,您可以使用所有标准函数的宽字符版本。例如,如果您有这样的代码:

long words = 0;
int in_word = 0;
int c;

while ((c = getchar()) != EOF)
{
    if (isspace(c))
    {
        if (in_word)
        {
            in_word = 0;
            words++;
        }
    }
    else
    {
        in_word = 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

c...您可以通过更改为 a wint_tgetchar()to getwchar()EOFtoWEOFisspace()to 来将其转换为宽字符版本iswspace()

long words = 0;
int in_word = 0;
wint_t c;

while ((c = getwchar()) != WEOF)
{
    if (iswspace(c))
    {
        if (in_word)
        {
            in_word = 0;
            words++;
        }
    }
    else
    {
        in_word = 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在没有解释性评论的情况下投反对票是不礼貌的。 (5认同)

bma*_*ies 2

去ICU看看吧。该库是您处理所有问题所需的。