输出与输入相同。怎么修?

时间:2018-10-15 12:52:28

标签: c utf-8 character-encoding

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;
}

2 个答案:

答案 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;
}