如何在字符级别操作Unicode字符串?

Mor*_*hai 1 c++ unicode winapi

有时在字符级别操纵字符串是不可避免的.

这里我有一个为基于ANSI/ASCII的字符串编写的函数,它仅用LF替换CR/LF序列,并且还用LF替换CR.我们之所以使用它,是因为传入的文本文件通常会因各种文本或电子邮件程序而产生混乱,因为各种文本或电子邮件程序使它们变得混乱,我需要它们采用一致的格式,以使解析/处理/输出在未来正常工作.

对于每个字符的单字节实现,这是从各种行结尾到LF的压缩的相当有效的实现:

// returns the in-place conversion of a Mac or PC style string to a Unix style string (i.e. no CR/LF or CR only, but rather LF only)
char * AnsiToUnix(char * pszAnsi, size_t cchBuffer)
{
    size_t i, j;
    for (i = 0, j = 0; pszAnsi[i]; ++i, ++j)
    {
        // bounds checking
        ASSERT(i < cchBuffer);
        ASSERT(j <= i);

        switch (pszAnsi[i])
        {
            case '\n':
                if (pszAnsi[i + 1] == '\r')
                    ++i;
                break;

            case '\r':
                if (pszAnsi[i + 1] == '\n')
                    ++i;
                pszAnsi[j] = '\n';
                break;

            default:
                if (j != i)
                    pszAnsi[j] = pszAnsi[i];
        }

    }

    // append null terminator if we changed the length of the string buffer
    if (j != i)
        pszAnsi[j] = '\0';

    // bounds checking
    ASSERT(pszAnsi[j] == 0);

    return pszAnsi;
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试将其转换为可以与多字节/ unicode字符串一起正常工作的东西,其中下一个字符的大小可以是多字节宽.

所以:

  1. 我只需要在有效的字符点(不在字符中间)查看字符
  2. 我需要正确复制作为被拒绝部分一部分的字符部分(即复制整个字符,而不仅仅是字节)

我知道_mbsinc()会给我一个真实角色下一个开始的地址.但是什么是Unicode(UTF16)的等价物,是否已经有原始的能够复制一个完整的字符(例如length_character(wsz))?

Mar*_*som 6

关于UTF-8的一个好处是,如果你只关心ASCII子集,你的代码根本不需要改变.非ASCII字符被编码为多字节序列,其中所有字节都设置了高位,使它们本身不在ASCII范围内.您的CR/LF更换应该无需修改即可使用.

UTF-16具有相同的属性.可以编码为单个16位实体的字符永远不会与需要多个实体的字符冲突.

  • @Mordachai:总是可以在UTF-16数据中查看单个16位代码单元,并确定以下三个中的哪一个:(1)它代表一个unicode代码点,(2)它是第一个代码两个单元一起表示代码点,(3)它是两个的第二个代码单元,它们一起代表一个代码点.范围"0xD800 - 0xDBFF"保留给(2),"0xDC00 - 0xDFFF"保留给(3).您可以使用伪装成UTF-16的错误编码数据来制造奇怪的案例,但除此之外不应该出现问题. (4认同)
  • @Mordachai,这是我的观点 - 多部分序列的后半部分*永远不会匹配'L'\n'或"L"\ r'. (3认同)
  • @Mordachai,如果用"前导字节"代表"单字节",那么你就是正确的.我通常会将"lead"解释为多部分序列的第一部分,并且它们在编码中占据了自己独特的空间,并且与其他任何东西都不匹配. (2认同)