有时在字符级别上不可避免地要操纵字符串。

在这里,我有一个为基于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;
}

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

所以:
  • 我只需要在一个有效的字符点(而不是在字符中间)看一个字符
  • 我需要正确复制被拒绝部分的一部分字符(即复制整个字符,而不仅仅是字节)

  • 我知道_mbsinc()会为我提供下一个真实字符开始的地址。但是Unicode(UTF16)的等效功能是什么,是否已经存在能够复制完整字符的原语(例如length_character(wsz))?

    最佳答案

    关于UTF-8的美丽之处之一是,如果您只关心ASCII子集,则根本不需要更改代码。非ASCII字符被编码为多字节序列,其中所有字节均设置了高位,从而使它们自身不在ASCII范围之内。您的CR / LF替代品应该可以正常工作而无需修改。

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

    10-08 08:11
    查看更多