读取C中的unicode文件时出错
我想使用以下代码读取C(Cygwin/GCC)中的unicode文件:读取C中的unicode文件时出错,c,gcc,cygwin,glibc,gio,C,Gcc,Cygwin,Glibc,Gio,我想使用以下代码读取C(Cygwin/GCC)中的unicode文件: #include <stdio.h> #include <stdlib.h> #include <glib.h> void split_parse(char* text){ char** res = g_strsplit(text, "=", 2); printf("Key = %s : ", res[0]); printf("Value = %s", res[
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
void split_parse(char* text){
char** res = g_strsplit(text, "=", 2);
printf("Key = %s : ", res[0]);
printf("Value = %s", res[1]);
printf("\n");
}
int main(int argc, char **argv)
{
setenv ("CYGWIN", "nodosfilewarning", 1);
GIOChannel *channel;
GError *err = NULL;
int reading = 0;
const gchar* enc;
guchar magic[2] = { 0 };
gsize bytes_read = 0;
const char* filename = "C:\\CONFIG";
channel = g_io_channel_new_file (filename, "r", &err);
if (!channel) {
g_print("%s", err->message);
return 1;
}
if (g_io_channel_set_encoding(channel, NULL, &err) != G_IO_STATUS_NORMAL) {
g_print("g_io_channel_set_encoding: %s\n", err->message);
return 1;
}
if (g_io_channel_read_chars(channel, (gchar*) magic, 2, &bytes_read, &err) != G_IO_STATUS_NORMAL) {
g_print("g_io_channel_read_chars: %s\n", err->message);
return 1;
}
if (magic[0] == 0xFF && magic[1] == 0xFE)
{
enc = "UTF-16LE";
}
else if (magic[0] == 0xFE && magic[1] == 0xFF)
{
enc = "UTF-16BE";
}
else
{
enc = "UTF-8";
if (g_io_channel_seek_position(channel, 0, G_SEEK_CUR, &err) == G_IO_STATUS_ERROR)
{
g_print("g_io_channel_seek: failed\n");
return 1;
}
}
if (g_io_channel_set_encoding (channel, enc, &err) != G_IO_STATUS_NORMAL) {
g_print("%s", err->message);
return 1;
}
reading = 1;
GIOStatus status;
char* str = NULL;
size_t len;
while(reading){
status = g_io_channel_read_line(channel, &str, &len, NULL, &err);
switch(status){
case G_IO_STATUS_EOF:
reading = 0;
break;
case G_IO_STATUS_NORMAL:
if(len == 0) continue;
split_parse(str);
break;
case G_IO_STATUS_AGAIN: continue;
case G_IO_STATUS_ERROR:
default:
//throw error;
reading = 0;
break;
}
}
g_free(str);
g_io_channel_unref(channel);
return(EXIT_SUCCESS);
}
在阅读时,我总是在While循环中的“g_io_channel_read_line”处收到以下错误消息:
0x800474f8“转换输入中的字节序列无效”
我做错了什么?如何使用glib在C中读取这样的文件
编辑:文件的hextump
您的文件包含3字节的UTF8 BOM(EF BB BF)。字节顺序标记 您的代码默认为UTF8,但不使用BOM表
channel, 0, G_SEEK_CUR, &err
s/b
此外,我建议将magic
代码扩展为读取4个字节,并明确识别BOM
channel, 0, G_SEEK_CUR, &err
如果找不到BOM,可以假设编码为NULL,我认为这是二进制的。或者抛出一个错误或修复任性的文本文件,或者,如果你是学究,按顺序尝试所有已知的编码类型
UTF32BE“\x00\x00\xFE\xFF”
UTF32LE“\xFF\xFE\x00\x00”
UTF8“\xEF\xBB\xBF”
UTF16BE“\xFE\xFF”
UTF16LE“\xFF\xFE”
二进制文件为空文本文件可能/可能不包括初始BOM(字节顺序标记)。显示文本文件前10个字节左右的十六进制转储。顺便说一句,除了3个编码之外,还有其他编码。GTG@chux已添加文件的hextump。
channel, 3, G_SEEK_CUR, &err