【问题标题】:isLetter with accented characters in CisLetter 与 C 中的重音字符
【发布时间】:2011-08-02 01:44:45
【问题描述】:

我想创建(或查找)一个 C 函数来检查 char c 是否为字母... 当然,我可以轻松地为 a-z 和 A-Z 做到这一点。

但是,如果测试 c == á,ã,ô,ç,ë 等会出现错误

可能这些特殊字符存储在一个字符以上...

我想知道: 这些特殊字符是如何存储的,我的函数需要接收哪些参数,以及如何去做? 我也想知道是否有任何标准功能已经这样做了。

【问题讨论】:

    标签: c testing char diacritics letter


    【解决方案1】:

    我认为您正在寻找iswalpha() 例程:

       #include <wctype.h>
    
       int iswalpha(wint_t wc);
    
    DESCRIPTION
       The iswalpha() function is the wide-character equivalent of
       the isalpha(3) function.  It tests whether wc is a wide
       character belonging to the wide-character class "alpha".
    

    它确实取决于当前locale(7)LC_CTYPE,因此它在应该同时正确处理多种类型输入的程序中使用可能并不理想。

    【讨论】:

      【解决方案2】:

      如果您正在使用单字节代码集,例如 ISO 8859-1 或 8859-15(或任何其他 8859-x 代码集),那么如果您还记得使用 isalpha() 函数将完成这项工作程序中的setlocale(LC_ALL, "");(或其他一些合适的setlocale() 调用)。没有这个,程序在 C 语言环境中运行,它只对 ASCII 字符(0x00..0x7F 范围内的 8859-x 字符)进行分类。

      如果您使用多字节或宽字符代码集(例如 UTF8 或 UTF16),则需要查看在 &lt;wchar.h&gt;&lt;wctype.h&gt; 中找到的宽字符函数。

      【讨论】:

      • ISO 8859-1 将是完美的。据你说,这是单字节......所以我需要将'ç'或'á'之类的字符声明为wchar_t还是我可以使用字符?而且...如何使用 setlocale() 来使用 ISO 8859-1 ?另外,如果我可以使用 char,例如,我如何声明一个包含 'á' 的 char 变量?很抱歉问了这么多问题,但我对这个话题很陌生。
      • 当我这样做时:char o = 'ç'; gcc 告诉我:main.c:9:11:警告:多字符字符常量 main.c:在函数“main”中:main.c:9:警告:隐式常量转换中的溢出
      • @joxnas:LANG、LC_ALL、LC_CTYPE 的环境设置是什么?您使用的是哪种终端仿真器?它的代码集是什么?编译器警告听起来好像您有一个 UTF-8 终端仿真器 - 这些天并不少见。而且很大程度上取决于您使用的 C 库。
      • locale 命令给了我这些:LANG=en_US.utf8;LC_CTYPE="en_US.utf8";LC_ALL="";终端模拟器是 GNOME Terminal 2.30.2 在菜单栏中有一个选项可以将编码设置为 ISO 8859-1,在 gvim(我使用的编辑器)中,有 :set fileencoding 命令。我尝试在 vim 中将文件编码设置为 latin1 (ISO 8859-1),char o = 'ç'; 现在效果很好。但是,要正确读取从 input(getchar) 到 1 字节字符的重音字符,我还需要在终端中设置编码。 setlocale() 是否允许我在我的程序中控制它?
      • @joxnas:不,setlocale() 不控制终端属性。很可能有一种以编程方式进行的方法,但它需要一些手动抨击——很可能是相当广泛的手动抨击。
      【解决方案3】:

      这些字符的存储方式取决于语言环境。在大多数 UNIX 系统上,它们将存储为 UTF8,而 Win32 机器可能会将它们表示为 UTF16。 UTF8 存储为可变数量的字符,而 UTF16 使用代理对存储 - 因此在 wchar_t(或 unsigned short)内(尽管顺便说一下,Windows 上的 sizeof(wchar_t) 仅为 2(而 *nix 上为 4),因此,如果使用代理对编码,您通常需要 2 个 wchar_t 类型来存储 1 个字符 - 在许多情况下都是如此)。

      如前所述,iswalpha() 例程将为您执行此操作,并记录在 here。它应该为您处理特定于语言环境的问题。

      【讨论】:

      • 不,这是不正确的,UTF16 也是可变长度的,只是每个代码点是 16 位,而不是 UTF8 中的 8 位。
      • 是的,但是每个字符只需要一个 wchar_t 类型。哦,实际上,除非你在 Windows 机器上将它们存储为 16 位而不是 32 位。是的,你是对的。
      • Nit:你很少需要两个 wchar_t,不是经常。
      【解决方案4】:

      你可能想要http://site.icu-project.org/。它为此提供了一个带有 API 的可移植库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-16
        • 2018-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多