繁体   English   中英

将字符串的第一个字符传递到另一个字符串中,并使用std :: stoi获取整数值,以测试它是使用UTF-8还是Unicode(UTF-16)

[英]Passing the first character of a string into another string and using std::stoi to get the integer value, to test if it us UTF-8 or Unicode(UTF-16)

想知道是否有人可以在这个问题上提供帮助?

众所周知,以UTF-8和Unicode(UTF-16)编码的.txt文件具有隐藏字符。

我正在编写一个程序,该程序采用具有不同编码UTF-8和Unicode(UTF-16)的选定.txt文件。 我需要获取字符串的第一个字符并将其存储。 我需要对该字符串进行处理,就是将其放入一个单独的字符串中,然后使用std :: stoi来获取隐藏字符的int值。

    //OPEN THE FILE IN BINARY
  std::fstream mazeFile(mazeFileLoc, std::ios::in | std::ios::binary);

  if (mazeFile.is_open())
  {
      //STORE THE FIRST CHARACTER AS AN CHAR VALUE
    char test = mazeFile.get();
    std::cout << "First Character is : " << test << std::endl;

    //PUT THE CHAR VALUE IN A STRING
    std::string strTest;
    strTest.insert(strTest.begin(), test);
    std::cout << "String First Character is : " << strTest << std::endl;

    //USE STOI TO GET THE INT VALUE OF STRING
    int testIntVal = std::stoi(strTest);
    std::cout << "Int Value of first character is : " << testIntVal << std::endl;

    mazeFile.close();
  }

我遇到的问题是,当我使用stoi时,在运行时会标记一个错误。

有谁知道为什么这可能会标记错误而不进行转换?

Git链接: https : //github.com/xSwalshx/ANN.git

std::stoi需要如下进行异常处理:

int testIntVal; 
try
{
    testIntVal = std::stoi(strTest);
    std::cout << "Int Value of first character is : " << testIntVal << std::endl;
}
catch(...)
{
    std::cout << "not a valid integer\n";
}

这不是检查文件编码的正确方法。

您必须检查BOM(字节顺序标记),如果文件具有BOM,则可以确定格式。

如果文件没有BOM,则您必须猜测格式是什么,您不确定。 如果文本查看器将内容显示为“ 123”,则将其存储为

0x31 0x32 0x33 //in UTF8 (same for ASCII characters)
0x31 0x00 0x32 0x00 0x33 0x00 //in UTF16
0x00 0x31 0x00 0x32 0x00 0x33 //in UTF16 big-endian

请注意,对于ASCII字符中的偶数字节,UTF16-LE的零,对于奇数字节的UTF16-LE的零,而UTF8没有零。 您可以从一个很弱的假设开始,即该文件仅包含ASCII字符。 然后猜测一下编码。 请参见下面的示例。

为了简化操作,您应该使用UTF8来存储文本。 在Windows中,只需将UTF16转换为UTF8并存储,然后读取UTF8并转换为UTF16。 这也将与其他系统兼容。

const int FORMAT_UTF8 = 0;
const int FORMAT_UTF16 = 1;
const int FORMAT_UTF16BE = 2;

int get_file_encoding(const char* filename)
{
    printf("filename: %s ", filename);
    unsigned char buf[100] = { 0 };
    std::ifstream fin(filename, std::ios::binary);
    fin.read((char*)buf, sizeof(buf));
    int size = fin.gcount();

    //check for BOM
    if(size >= 3 && memcmp(buf, "\xef\xbb\xbf", 3) == 0)
    {
        printf("UTF8\n");
        return FORMAT_UTF8;
    }

    if(size >= 2 && memcmp(buf, "\xff\xfe", 2) == 0)
    {
        printf("UTF16\n");
        return FORMAT_UTF16;
    }

    if(size >= 2 && memcmp(buf, "\xfe\xff", 2) == 0)
    {
        printf("UTF16 big endian\n");
        return FORMAT_UTF16BE;
    }

    //BOM not found, let's take a guess!
    for(int i = 0; i < size - 1; i += 2)
    {
        if(buf[i + 1] == 0)
        {
            printf("assume UTF16\n");
            return FORMAT_UTF16;
        }

        if(buf[i] == 0)
        {
            printf("assume UTF16 big endian\n");
            return FORMAT_UTF16BE;
        }
    }

    printf("Assume ASCII or UTF8\n");
    return FORMAT_UTF8;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM