代码之家  ›  专栏  ›  技术社区  ›  Anteru

在C/C++中,在内存中存储UTF-8字符串的最佳方法是什么?

  •  9
  • Anteru  · 技术社区  · 16 年前

    看着 unicode standard ,他们建议使用纯咖啡 char 用于存储UTF-8编码字符串的。这是否与C++和Basic一样工作? std::string ,或者是否存在UTF-8编码可能产生问题的情况?

    烧焦 用于存储的数组,但我仍然需要编写如下函数 strlen 就我个人而言,它处理编码文本,导致据我所知的问题,标准例程要么仅为ASCII,要么期望宽文本(16位或更多),这是unicode标准不推荐的。到目前为止,我找到的关于编码的最好来源是一篇关于 Joel's on Software ,但它不能解释我们可怜的C++开发者应该使用什么:

    6 回复  |  直到 16 年前
        1
  •  5
  •   Carl Seleborg    16 年前

    有一个图书馆叫做“ UTF8-CPP ,它允许您将UTF-8字符串存储在标准std::string对象中,并提供了枚举和操作UTF-8字符的附加函数。

    我还没有测试过它,所以我不知道它值多少钱,但我正在考虑自己使用它。

        2
  •  3
  •   MSalters    16 年前

    strlen统计第一个\0之前的非空字符数。在UTF-8中,该计数是一个正常数(使用的字节数),但该计数不是字符数(一个UTF-8字符通常为1-4个字符)。基本\u字符串不存储\0,但它也保留字节计数。

    strcpy或basic_string copy ctor复制所有字节,但不要看得太近。

    由于UTF_8的编码方式,查找子字符串工作正常。字符的第一个字节的允许值不同于第二到第四个字节(前者从不以10xxxxxx开头,后者总是以10xxxxxx开头)

    获取子字符串很棘手-如何指定位置?如果通过搜索ASCII文本标记(例如,[和])找到开始和结束,那么就没有问题。你只需得到中间的字节,这也是一个有效的UTF8字符串。您不能对位置进行编码,甚至不能对相对偏移进行编码。即使是+1个字符的相对偏移量也很困难;这是多少字节?您最终将编写一个类似SkipOneChar的函数。

        3
  •  3
  •   sastanin    16 年前

    举个例子 ICU library (C,C++,java):

    #include <iostream>
    #include <unicode/unistr.h> // using ICU library
    
    int main(int argc, char *argv[]) {
        // constructing a Unicode string
        UnicodeString ustr1("Привет"); // using platform's default codepage
        // calculating the length in characters, should be 6
        int ulen1=ustr1.length();
        // extracting encoded characters from a string
        int const bufsize=25;
        char encoded[bufsize];
        ustr1.extract(0,ulen1,encoded,bufsize,"UTF-8"); // forced UTF-8 encoding
        // printing the result
        std::cout << "Length of " << encoded << " is " << ulen1 << "\n";
        return 0;
    }
    

    建筑状

    $ g++ -licuuc -o icu-example{,.cc}
    

    跑步

    $ ./icu-example
    Length of Привет is 6
    

    我可以在Linux上使用GCC4.3.2和libicu3.8.1。请注意,无论系统语言环境是什么,它都以UTF-8打印。如果您的不是UTF-8,您将无法正确看到它。

        4
  •  2
  •   BenMorel Manish Pradhan    11 年前

    这取决于您想对UTF8字符串执行什么操作。如果您感兴趣的只是读入和读出UTF8字符串,那么只要您设置了正确的语言环境,这一切都可以工作。我们这样做已经有一段时间了。我们有几个服务器进程不处理字符串本身。这些字符串由用户在Java中设置,以UTF8的形式到达,我们在标准的c str缓冲区中处理它们。然后我们将数据发送回Java,Java将数据转换回Java。

    如果需要UTF8字符的长度,则需要能够为您处理翻译的函数。

    但是你可以自己滚,比如说 utf8-strlen

        5
  •  1
  •   user52875    16 年前

    我们解决的问题是:将UTF8存储在std::string中。现在,除了计算长度之类的事情外,您可以执行大多数操作。使用UTF8->std::wstring转换函数(例如boost::from_utf8),用于在需要此类操作时转换为std::wstring。

        6
  •  0
  •   sastanin    16 年前

    从…起 UTF-8 and Unicode FAQ: C support for Unicode :

    #include <stdio.h>
    #include <locale.h>
    
    int main()
    {
      if (!setlocale(LC_CTYPE, "")) {
        fprintf(stderr, "Can't set the specified locale! "
                "Check LANG, LC_CTYPE, LC_ALL.\n");
        return 1;
      }
      printf("%ls\n", L"Schöne Grüße");
      return 0;
    }
    

    也来自 here :

    wchar_t* 弦与弦的家族 与之相关的功能,例如 wprintf , wcslen wcslcat 你是 处理Unicode值。在 C++世界,你可以使用 std::wstring 到 提供友好的界面。我唯一的 投诉是这些是32位(4 字节)字符,因此它们是内存 这一选择是,它保证了每一项 可以表示可能的字符 一个值。

    这可能是Linux特有的。有一个ICU图书馆来处理复杂的事情。