使用 iconv() 将 UTF-16LE 转换为 UTF-8

convert UTF-16LE to UTF-8 with iconv()

我正在尝试使用 Linux 中的 iconv() 将 UTF-16LE 转换为 UTF-8。

我认为它完成了..

但是我遇到了一些麻烦..我的代码..

而且我认为两个代码相同,但第一个不起作用。只有第二个工作。

#include "stdio.h"
#include "string.h"
#include "iconv.h"
#include "errno.h"
#if 1
int fn2Utf8(char inBuf[], char outBuf[]) {
    size_t readBytes = sizeof(inBuf);
    size_t writeBytes = sizeof(outBuf);
    char* in = inBuf;
    char* out = outBuf;

    iconv_t convert = iconv_open("UTF-8","UTF-16LE");
    if (iconv(convert, &in, &readBytes, &out, &writeBytes) < 0) {
        return (-1);
    }
    iconv_close(convert);
    printf("[%s] [%s]\n", inBuf, outBuf);
    return (out - outBuf);
}
int main() {
    char inBuf[128] ="\x5c\x00\xbd\xac\x01\xc6\x00\xd3\x5c\x00\x00\xb3\x78\xc6\x44\xbe\x5c\x00\x2a\x00\x00\x00";
    char outBuf[128];
    fn2Utf8(inBuf, outBuf);
    return 0;
}
#else
int main() {
    char inBuf[128] = "\x5c\x00\xbd\xac\x01\xc6\x00\xd3\x5c\x00\x00\xb3\x78\xc6\x44\xbe\x5c\x00\x2a\x00\x00\x00";
    char outBuf[128];
    size_t readBytes = sizeof(inBuf);
    size_t writeBytes = sizeof(outBuf);
    char* in = inBuf;
    char* out = outBuf;

    iconv_t convert = iconv_open("UTF-8","UTF-16LE");
    if (iconv(convert, &in, &readBytes, &out, &writeBytes) < 0) {
    return (-1);
    }
    iconv_close(convert);
    printf("[%s] [%s]\n", inBuf, outBuf);
    return 0;
}
#endif

你可以用 if 0 -> if 1 编译两种类型的代码

我需要 if 1 方法。

这是问题所在:

size_t readBytes = sizeof(inBuf);
size_t writeBytes = sizeof(outBuf);

当您将数组传递给函数时,它们 衰减 指向指向其第一个元素的指针。您的来电

fn2Utf8(inBuf, outBuf);

等于

fn2Utf8(&inBuf[0], &outBuf[0]);

这意味着函数中的参数不是数组,而是指针。当您对指针执行 sizeof 时,您会得到指针的大小而不是它指向的内容。

有两种解决方案:第一种是将数组的长度作为参数传递给函数,然后使用它。第二个,至少对于 inBuf 参数来说,是依赖于它是一个以 null 结尾的字符串这一事实,并使用 strlen 代替。

第二种方式,使用 strlen,正如我已经说过的,仅适用于 inBuf,但不适用于必须使用第一种方式并通过的 outBuf尺寸作为参数。


如果在没有函数的情况下在程序中工作,因为那么你是在 数组 而不是指针上做 sizeof。当你有一个数组而不是一个指针时,sizeof 会给你数组的字节大小。