我必须将配置信息写入Linux中的文件,而配置信息包含汉字。
我不是使用wchar_t
,而是使用char数组,这是正确的吗?
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define MSG_LEN 4096
int save_config_info(const char *path, char* message)
{
FILE *fp = NULL;
fp = fopen(path, "wb");
if (!fp)
{
//print error message
return -1;
}
if (fwrite(message, 1, strlen(message), fp) != strlen(message))
{
//print error message
fclose(fp);
return -1;
}
fclose(fp);
return 0;
}
int main()
{
//config contain chinese character
char str[MSG_LEN] = "配置文件中包含中文";
char path[PATH_MAX] = "example.txt";
save_config_info(path,str);
return 0;
}
如果源代码编码为ISO-8859-1,则生成example.txt并使用cat来显示??
但是使用utf-8更改源代码编码,一切正常。
我的问题是:
因为我不能确保源文件的编码,所以有什么优雅的方式来处理汉字。
我希望example.txt看起来总是正确的。
[root workspace]#file fork.c
fork.c: C source, ASCII text
[root workspace]#gcc -g -o fork fork.c
[root workspace]#
[root workspace]#./fork
[root workspace]#
[root workspace]#
[root workspace]#file example.txt
example.txt: ASCII text, with no line terminators
[root workspace]#
[root workspace]#cat example.txt
?????????[root workspace]#
[root workspace]#
[root workspace]#
[root workspace]#file fork.c
fork.c: C source, UTF-8 Unicode text
[root workspace]#
[root workspace]#gcc -g -o fork fork.c
[root workspace]#./fork
[root workspace]#
[root workspace]#file example.txt
example.txt: UTF-8 Unicode text, with no line terminators
[root workspace]#cat example.txt
配置文件中包含中文[root workspace]#
答案 0 :(得分:1)
是否存在仅使用ASCII字符来表示ASCII中找不到的字符的优雅方法?不。
但是有可能以微不足道的方式做到这一点。
char str[MSG_LEN] = "\xE9\x85\x8D\xE7\xBD\xAE\xE6\x96\x87\xE4\xBB\xB6\xE4\xB8\xAD\xE5\x8C\x85\xE5\x90\xAB\xE4\xB8\xAD\xE6\x96\x87";
当然,就像您的原始程序一样,这假定查看文件名的人员(例如,使用ls
)的语言环境基于UTF-8。
答案 1 :(得分:0)
我不使用wchar_t,而是使用char数组,这对吗?
我会拒绝。 char
的默认字符集和编码是由实现定义的(可以是EBCDIC或ASCII或UTF-8或碰巧使用的源文件或其他任何东西),而wchar_t
的默认字符集和编码是也是实现定义的(可以是UTF-16LE或...)。
如果需要输出为UTF-8;然后(特别是对于可移植代码),您需要忽略C编译器的随机默认值。您还应该避免使用char
,因为无论是有符号的还是无符号的都是实现定义的,请避免使用unsigned char
,因为实际上并不能保证它是8位的,并且避免使用wchar_t
(因为它的大小是实现定义)
具体来说(对于UTF-8),我将使用uint8_t
,例如:
uint8_t str[] = 0xE9, 0x85, 0x8D, 0xE7, 0xBD, 0xAE, 0xE6, 0x96, 0x87, 0xE4, 0xBB, 0xB6,
0xE4, 0xB8, 0xAD, 0xE5, 0x8C, 0x85, 0xE5, 0x90, 0xAB, 0xE4, 0xB8, 0xAD,
0xE6, 0x96, 0x87, 0x00;
当然,如果您希望文件包含CNS-11643(或其他任何文件),也可以这样做。您只需要找到一个合适的类型,然后找到“该类型的数字数组”(例如,可以在使用所需字符集和编码的文本文件上使用类似hexdump
的实用程序)。
答案 2 :(得分:0)
要可靠地获取UTF-8字符串而不管使用哪种编码方式
char str[] = u8"\u914D\u7F6E\u6587\u4EF6\u4E2D\u5305\u542B\u4E2D\u6587";
char
也可以是char8_t
通过这种方式,您无需找到已编码的UTF-8字节,并且在需要其他编码(例如UTF-16或UTF-32)时,只需将类型和前缀(u8
更改为{{1 }}或u
)