1

我有两个问题: 1) 测试此代码时,在 buf 的前面显示了一些额外的字符。(当文件为空时,fsize 出于某种原因设置为 3)。

2)该文件包含utf-8字符并且在控制台中无法正确显示,我尝试将语言环境设置为LC_ALL,但似乎没有任何效果。

void display_title(void)
{
    FILE *fh;
    char *buf;
    long fsize;

    fh = fopen("title.txt", "r");
    if (fh == NULL)
    {
        fprintf(stderr, "Unable to open title.txt for read\n");
        return;
    }

    fseek(fh, 0L, SEEK_END);
    fsize = ftell(fh);
    rewind(fh);
    buf = malloc(sizeof(char)*fsize);

    fread(buf, fsize, 1, fh);
    fclose(fh);

    fwrite(buf, fsize, 1, stdout);
    free(buf);
}

编辑:所以我写了一个函数来检查文件的编码,但有些东西仍然关闭。我检查了文件,我知道它是 UTF_8,但它没有在我的函数中注册。我觉得某处有一个错误,但我没有看到它。

// Check for BOM in file
// ERROR : file too small
// NONE : does not exist
// UTF_8_ENCODING : for utf_8 enoding found
// UTF_16_ENCODING : for utf_16 encoding found
// UTF_32_ENCODING : for utf_32 encoding found
int check_encoding(int fd)
{
    char *buf;
    off_t fsize;

    fsize = lseek(fd, 0L, SEEK_END);

    if (fsize < 2)
        return ERROR;

    buf = (char*)malloc(2 * sizeof(char));
    lseek(fd, 0L, SEEK_SET);
    read(fd, buf, 2);

    if (!strncmp(buf, UTF_16_BE, 2) ||
        !strncmp(buf, UTF_16_LE, 2))
    {
        free(buf);
        return UTF_16_ENCODING;
    }

    if (fsize >= 3)
    {
        realloc(buf, 3);

        if (!strncmp(buf, UTF_8, 3))
        {
            free(buf);
            return UTF_8_ENCODING;
        }
    }

    if (fsize >= 4)
     {
        realloc(buf, 4);

        if (!strncmp(buf, UTF_32_BE, 4) ||
            !strncmp(buf, UTF_32_LE, 4))
        {
            free(buf);
            return UTF_32_ENCODING;
        }
    }

    free(buf);
    return FALSE;
}
4

1 回答 1

1

很难说出为什么 UTF-8 没有在您的控制台上正确显示,但我认为开头的三个额外字节有一个简单的原因:很可能您的文件以字节顺序标记 (BOM)开头

编辑:对于 UTF-8 编码文件,BOM(如果存在)将始终是字节序列0xEF,0xBB,0xBF。因此,如果要处理可能包含或不包含 BOM 的文件,可以只读取前三个字节,检查它们的值,如果它们是 BOM,则忽略它们。

如果您不知道文件的编码(UTF-8、UTF-16、...),您可以使用 BOM 来确定它。我链接到的维基百科文章显示了它是如何以不同的编码表示的。

于 2013-10-09T14:42:17.110 回答