ANSI到UTF-8转换器。主要问题是输出与输入相同。如何解决?
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[], char *envp[])
{
FILE *SrcFile;
FILE *DstFile;
char ch;
wchar_t wch;
if((SrcFile = fopen("input.txt", "rb")) == NULL)
return 1;
if((DstFile = fopen("output.txt","wb+")) == NULL)
return 1;
fputc(0xFF, DstFile);
fputc(0xFE, DstFile);
while(TRUE)
{
ch = fgetc(SrcFile);
if(feof(SrcFile))
break;
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
&ch, 1, &wch, 1);
fputwc(wch, DstFile);
}
fclose(SrcFile);
fclose(DstFile);
return 0;
}
答案 0 :(得分:1)
根据设计,底部127个字符在ASCII / ANSI和UTF-8之间是二进制兼容的。所以应该没有区别。
您不应在UTF-8文件内容中包含BOM(字节顺序标记),因为这是不必要的,因为UTF-8的字节流是唯一的,因此不需要处理“字节序”问题。另外,添加BOM可能会破坏某些接受ANSI的应用程序。
答案 1 :(得分:0)
在Windows中,您可以从ANSI转换为UTF16,然后从UTF16转换为UTF8。
您不能一次在1个字节的字符集之间转换。整个文件必须读入缓冲区并进行转换。请注意,每个Unicode代码点在UTF8中为1到4个字节,而在UTF16中为2或4个字节,在ANSI中始终为1个字节。
int main(void)
{
FILE* src = fopen("source.txt", "rb");
if(!src) return 0;
FILE* dst = fopen("destination.txt", "wb");
if(!dst) return 0;
fseek(src, 0, SEEK_END);
long filesize = ftell(src);
char *ansi = malloc(filesize);
fseek(src, 0, SEEK_SET);
fread(ansi, 1, filesize, src);
int codepage = CP_ACP;
int u16size = MultiByteToWideChar(codepage, 0, ansi, filesize, NULL, 0);
wchar_t *u16 = malloc(u16size * sizeof(wchar_t));
MultiByteToWideChar(codepage, 0, ansi, filesize, u16, u16size);
int u8size = WideCharToMultiByte(CP_UTF8, 0, u16, u16size, NULL, 0, NULL, FALSE);
char *u8 = malloc(u8size);
WideCharToMultiByte(CP_UTF8, 0, u16, u16size, u8, u8size, NULL, FALSE);
fwrite(u8, 1, u8size, dst);
return 0;
}