C ++:从文件中读取alt键符号

时间:2016-03-08 11:16:23

标签: c++ file-io utf-8

我正在尝试从一个Unicode UTF-8文件中读取 Alt 键符号,然后写入另一个。

输入文件如下所示>

  

ỊịỌọỤụṄṅ

输出文件如下所示>

  

239 187 191 225 187 138 225 187 139 225 187 140 225 187 141 225 187   164 225 187 165 225 185 132 225 185 133(每3位数组合后'\ n',而不是'')

代码:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <Windows.h>


///convert as ANSI - display as Unicode
std::wstring test1(const char* filenamein)
{
    std::wifstream fs(filenamein);
    if(!fs.good()) 
    { 
        std::cout << "cannot open input file [" << filenamein << "]\n" << std::endl;  

        return NULL; 
    }

    wchar_t c; 
    std::wstring s;

    while(fs.get(c)) 
    { 
        s.push_back(c); 
        std::cout << '.' << std::flush; 
    }

    return s;

}

int printToFile(const char* filenameout, std::wstring line)
{
    std::wofstream fs;

    fs.open(filenameout);

    if(!fs.is_open())
        return -1;

    for(unsigned i = 0; i < line.length(); i++)
    {
        if(line[i] <= 126)  //if its standard letter just print to file
            fs << (char)line[i];
        else  //otherwise do this.
        {
            std::wstring write = L"";

            std::wostringstream ss;
            ss << (int)line[i];

            write = ss.str();

            fs << write;
            fs << std::endl;
        }
    }

    fs << std::endl;


    //2nd test, also fails
    char const *special_character[] = { "\u2780", "\u2781", "\u2782",
  "\u2783", "\u2784", "\u2785", "\u2786", "\u2787", "\u2788", "\u2789" };

    //prints out four '?'
    fs << special_character[0] << std::endl;
    fs << special_character[1] << std::endl;
    fs << special_character[2] << std::endl;
    fs << special_character[3] << std::endl;

    fs.close();

    return 1;
}

int main(int argc, char* argv[])
{
    std::wstring line = test1(argv[1]);

    if(printToFile(argv[2], line) == 1)
        std::cout << "Writing success!" << std::endl;
    else std::cout << "Writing failed!" << std::endl;



    return 0;
}

我期待的是与此表中的值类似的东西:

  

http://tools.oratory.com/altcodes.html

1 个答案:

答案 0 :(得分:2)

好的,根据您的代码和评论,我理解以下内容:

  • 您的输入文件包含UTF-8编码的字符串
  • 您正在Windows上将其读取为宽字符,但没有添加任何区域设置

所以这是实际发生的事情:

您的代码正确地一次一个字节地读取文件,作为ANSI文件(就好像它是win1252编码的)。然后,您的程序将显示所有字节的代码值。我可以确认你在帖子中显示的字节列表是utf-8编码字符串ỊịỌọỤụṄṅ,除了notepad ++在开始时添加了字节顺序标记(U + FEFF),UTF8中通常不使用文件 - BOM是3字节239 187 191(十进制)或0xef 0xbb 0xbf(六进制)

那你能做什么?

一个简单的解决方案(当您使用Windows时)将要求notepad ++将文件编码为UTF16LE,这是Windows中的本机u​​nicode格式。这样你实际上会读取unicode字符。

另一种方法是指示您的代码将文件处理为UTF8。这对于Linux来说是微不足道的,但在Windows上,自从VC2010以来只能正确处理UTF8,这可能很棘手。另一个post from SO显示了如何在C ++流中灌输UTF8语言环境。

我很抱歉没有提供代码,但我只有一个不支持UTF8流的旧版VC2008 ...而且我讨厌提供未经测试的代码。