【问题标题】:How to find a encoding of txt file in c++?如何在 C++ 中找到 txt 文件的编码?
【发布时间】:2014-02-18 11:14:43
【问题描述】:

。 我是 C++ 新手。我必须找出用户传递的文件包含的编码类型。但我不知道如何检查文件的编码。所以我需要打印文件是unicode还是ansi或unicode big endian还是utf8。我搜索了很多但找不到解决方案。直到现在我已经打开了一个文件:

#include "stdafx.h"
#include <iostream.h>
#include <stdio.h>
#include<conio.h>
#include <fstream>
using namespace std;



int _tmain(int argc, _TCHAR* argv[])
{
    fstream f;
    f.open("c:\abc.txt", fstream::in | fstream::out); /* Read-write. */


    getch();
    return 0;
}

所以请谁能告诉我这个的代码解决方案。

如果我正在访问记事本文件怎么办?

提前谢谢..

【问题讨论】:

  • 你不能只找出正在使用的编码,你只能预测它。您应该阅读以下内容:joelonsoftware.com/articles/Unicode.html
  • 如果文件有 BOM,则使用 BOM。如果没有,请询​​问用户。这是唯一确定的方法。
  • @jonathan 我如何检查文件中的 BOM,你能解释一下吗? .
  • 记得在你传递的路径中转义你的 \ 以打开或只是做我所做的并使用 / 而不是 \ 路径。

标签: c++


【解决方案1】:

你不能。

您可以做的最好的事情是guess it 或将编码保存为文件结构的一部分(如果可以的话)。

【讨论】:

  • 为什么notepad++总是知道以正确的格式显示txt文件?
  • 没有!它可以很好地猜测英文文本。但是我已经多次看到它在使用非英语资源时失败了,比如俄语可以是 Windows-1251 或 KOI8-R(以及其他几个),所以我不得不去 Encoding -> Character Set -> Cyrillic 并尝试情侣,之前我可以阅读文本。
【解决方案2】:

正如here 所讨论的那样,您唯一能做的就是guess按照最有可能抛出无效匹配的最佳顺序

您应该按以下顺序检查:

  • 开头是否有 UTF-16 BOM?那么它可能是UTF-16。使用 BOM 指示它是大端还是小端,然后检查文件的其余部分是否符合。
  • 开头是否有 UTF-8 BOM?那么它可能是UTF-8。检查文件的其余部分。
  • 如果以上没有产生正匹配,请检查整个文件是否为有效的 UTF-8。如果是,则可能是 UTF-8。
  • 如果上述结果没有得到肯定匹配,则可能是 ANSI。

【讨论】:

  • 还有一个应该考虑的 UTF-32 BOM。除此之外,它主要是猜测,最有可能的猜测取决于语言环境。我在哪里(或曾经在哪里),如果整个文件都是合法的 UTF-8,那可能就是这样;否则,ISO 8859-1 或 ISO 8859-15(但到那时,你真的在​​猜测)。
  • 另外,如果每隔一个字节为 0,或者大多数为 0,那么它可能是 UTF-16、大端或小端,具体取决于哪个字节为 0。四个 0 中的三个字节也是如此, 和 UTF-32。
【解决方案3】:

您无法知道文本文件的编码是什么。一种方法是在文件开头查找 BOM,这将告诉您文本是否在 Unicode 中。但是,BOM 不是强制性的,因此您不能依赖它来区分 Unicode 和其他编码。

提出这个问题的一个很常见的方法是there is no such thing as plain text

我是西班牙人,您可以在这里轻松找到 7 位 ASCII、扩展 ASCII、ISO-8859-1(又名拉丁语 1,其中包括西欧所需的许多常见额外字符)和 UTF 格式的文本文件各种口味。

希望这会有所帮助。

【讨论】:

    【解决方案4】:

    文件通常用文件头来表示它们的编码。
    正如其他人所建议的那样,您永远无法确定文件真正使用的是什么编码

    按照以下链接了解总体思路:
    Using Byte Order Marks
    FILE SIGNATURES TABLE

    【讨论】:

      【解决方案5】:

      在这里我找到了一种检测记事本文件的方法,无论是 Unicode、Big Endian、UTF8 还是简单的 ANSI 文件:

      我发现当我默认将文件保存在记事本中时,它会在文件开头存储标记字节(BOM)。所以我决定按照这个问题中的早期建议使用它。

      首先我读取了文件的 1 个字节。 我早就知道了

      1. 如果文件是 Unicode 文件,那么它的前两个字符存储 FE FF,即 254 255 是它的十进制等价物。
      2. 如果文件是 UTF8 文件,那么它的第一个字符存储 FF,239 是它的十进制等值。

      这里是代码:

      #include<conio.h>
      #include<stdio.h>
      #include<string.h>
      int main()
      {
              FILE *fp=NULL;
              int c;
              int i = 0;
              fp=fopen("c:\\abc.txt","rb");
      
              if (fp != NULL)
              {
                  while (i<=3)
                  {
                              c = fgetc(fp);    
                              printf("%d",c);
                                  if(c==254)
                                  {
                                      printf("Unicode Big Endian File");
                                  }
                                  else if(c==255)
                                  {
                                      printf("Unicode Little Endian File");
                                  }
                                  else if(c==239)
                                  {
                                      printf("UTF8  file");
                                  }
                                  else 
                                  {
                                      printf("ANSI File");
                                  }
      
                    }
                    fclose(fp);
      
             }
      
              
              getchar();
      
          return 0;
      }
      

      这对我来说很好。希望对其他人也有用。

      【讨论】:

      • 没有“Unicode Big Endian”这样的东西。 Unicode 是一个非常大的字符集,它将数字分配给代码点。它不处理将这些数字编码为字节流。那是 Unicode 编码 的工作,例如 UTF-8、UTF-16LE、UTF-16BE、UTF-32LE、UTF-32BE。请阅读Byte order mark 以编写更好的代码。
      【解决方案6】:

      用记事本++打开你的文件,进入顶部菜单的编码查看文件See here的编码类型

      【讨论】:

      • 这是一个编程网站,解决方案必须涉及编程。 OP 正在询问如何查找编码 in C++.
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多