老实说,我只是没有在C++标准库中得到以下设计决定.将宽字符写入文件时,将wofstream转换wchar_t为char字符:
#include <fstream>
#include <string>
int main()
{
using namespace std;
wstring someString = L"Hello StackOverflow!";
wofstream file(L"Test.txt");
file << someString; // the output file will consist of ASCII characters!
}
Run Code Online (Sandbox Code Playgroud)
我知道这与标准有关codecvt.还有codecvt的utf8在Boost.此外,还有一个codecvt用于utf16由马丁·约克在这里SO.现在的问题是,为什么在standard codecvt转换宽字符?为什么不按原样写人物!
另外,我们是否会unicode streams使用C++ 0x或者我在这里遗漏了什么?
我有一个wstring声明如此:
// random wstring
std::wstring str = L"abcàdëefŸg€hhhhhhhµa";
Run Code Online (Sandbox Code Playgroud)
文字将是UTF-8编码,因为我的源文件是.
[编辑:根据Mark Ransom,情况不一定如此,编译器将决定使用什么编码 - 让我们假设我从例如UTF-8编码的文件中读取此字符串]
我非常希望将其转换为文件读取(当文本编辑器设置为正确的编码时)
abcàdëefŸg€hhhhhhhµa
Run Code Online (Sandbox Code Playgroud)
但是ofstream不是很合作(拒绝接受wstring参数),并且wofstream据说需要知道语言环境和编码设置.我只想输出这组字节.通常如何做到这一点?
编辑:它必须是跨平台的,不应该依赖于UTF-8编码.我碰巧有一组存储在a中的字节wstring,并希望输出它们.它很可能是UTF-16或纯ASCII.
我想通过我声明的两个指针将文本输出到文件:
wchar_t *Col1="dsffsd", *Col2="sdfsf";
Run Code Online (Sandbox Code Playgroud)
这是我尝试过的:
std::ofstream fout;
fout.open(NativeDatabasePathHist);
fout<<"testing";
fout<<" "<<Col1<<" "<<Col2;
fout.close();
Run Code Online (Sandbox Code Playgroud)
这就是我得到的:
测试113 113
为什么当我打印Col1和Col2,我得到的数字,而不是字符串?
我使用VS2008编写了以下程序:
#include <fstream>
int main()
{
std::wofstream fout("myfile");
fout << L"???????? ?????? Österreich ?????? ????" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译它时,IDE问我是否要将我的源文件保存为unicode,我说"是的,请".
然后我运行程序,myfile出现在我项目的文件夹中.我用记事本打开它,文件是空的.我记得记事本只支持ASCII数据.我用写字板打开它,它仍然是空的.最后,我内心的小天才敦促我查看文件大小,毫不奇怪它是0字节.所以我重建并重新启动了程序,没有任何效果.最后,我决定向StackOverflow上非常聪明的人询问我缺少的东西,我在这里:)
编辑:
在上述聪明人留下一些评论之后,我决定按照他们的建议重写这个程序:
#include <fstream>
#include <iostream>
int main()
{
std::wofstream fout("myfile");
if(!fout.is_open())
{
std::cout << "Before: Not open...\n";
}
fout << L"???????? ?????? Österreich ?????? ????" << std::endl;
if(!fout.good())
{
std::cout << "After: Not good...\n";
}
}
Run Code Online (Sandbox Code Playgroud)
建造它.跑吧.并且...控制台清楚地读到了,令我惊讶的是:"之后:不好......".所以我编辑了我的帖子以提供新的信息,并开始等待答案,这可以解释为什么这是我能做什么.:)
我目前正在编写一个应用程序,它要求我在任意窗口上调用GetWindowText并将该数据存储到文件中以供以后处理.长话短说,我注意到我的工具在"战地3"中失败了,我将问题缩小到其窗口标题中的以下字符:http: //www.fileformat.info/info/unicode/char/2122/index. HTM
所以我创建了一个小测试应用程序,它只执行以下操作:
std::wcout << L"\u2122";
Run Code Online (Sandbox Code Playgroud)
低并且看到在程序的其余部分中断输出到控制台窗口.
当MessageBoxW等API显示它时,为什么MSVC STL会阻塞这个角色(我假设其他人)?
如何将这些字符打印到我的文件中?
在Windows 7 x64下测试VC10和VC11.
抱歉这个构造不好的帖子,我在这里撕扯我的头发.
谢谢.
编辑:
最小的测试用例
#include <fstream>
#include <iostream>
int main()
{
{
std::wofstream test_file("test.txt");
test_file << L"\u2122";
}
std::wcout << L"\u2122";
}
Run Code Online (Sandbox Code Playgroud)
预期结果:'™'字符打印到控制台和文件.观察结果:文件已创建但为空.没有输出到控制台.
我已经确认我用于我的控制台的字体能够显示有问题的字符,并且该文件肯定是空的(大小为0字节).
编辑:
进一步的调试表明,在流中设置了'failbit'和'badbit'.
编辑:
我也尝试过使用Boost.Locale,即使全新的语言环境充满了所有标准流,我也遇到了同样的问题.
我想写一个std::wstring文件,需要读取该内容std:wstring.当字符串为时,会发生这种情况L"<Any English letter>".但是当我们有像孟加拉语,卡纳达语,日语等字符,任何类型的非英语字母时,问题就出现了.试过各种选择,如:
std::wstring为std::string写入文件并将读取时间读取为std::string转换为std::wstring
std::wstringwofstream,这对于母语字母也没有帮助 std::wstring data = L"?????? ?????????";平台是mac和Linux,语言是C++
码:
bool
write_file(
const char* path,
const std::wstring data
) {
bool status = false;
try {
std::wofstream file(path, std::ios::out|std::ios::trunc|std::ios::binary);
if (file.is_open()) {
//std::string data_str = convert_wstring_to_string(data);
file.write(data.c_str(), (std::streamsize)data.size());
file.close();
status = true;
}
} catch (...) {
std::cout<<"exception !"<<std::endl;
}
return status;
}
// Read Method
std::wstring
read_file(
const char* filename
) …Run Code Online (Sandbox Code Playgroud) 我知道ICU和小型库,比如代码项目上的utf8(忘记了确切的名称),但这些都不是我想要的.
我真正想要的是像ICU这样的东西,但是以更友好的方式结束.
特别:
如果不存在这样的库,是否可以使用标准c ++类包装ICU,所以我可以创建一个与std :: string和std :: wstring具有相同用法的ustring,并且还可以实现流的版本(最好是它们与现有的完全兼容,即我可以将它传递给期望std :: ostream的函数,并且它将在其内部格式和ascii(或utf-8)之间执行转换)?假设可能会有多少工作?
编辑:还看了c ++ 0x标准并注意到utf8,utf16和utf32的文字,这是否意味着标准库(例如字符串,流等)将完全支持那些编码和它们之间的转换?如果是这样,任何人都知道Visual Studio将支持这些功能需要多长时间?
EDIT2:至于使用现有的c ++支持,我会查找locale和facet的东西.
我遇到的一个问题是,当使用围绕wchar_t定义的流(在Windows下为文件i/o时为2个字节)时,它似乎仍然使用ascii作为文件自己.
std::wofstream file(L"myfile.txt", std::ios::out);
file << L"Hello World!" << std::endl;
Run Code Online (Sandbox Code Playgroud)
导致文件中的以下十六进制
48 65 6C 6C 6F 20 57 6F 72 6C 64 0D 0A
这显然是ascii而不是预期的utf-16输出:
FF FE 48 00 65 00 6C 00 6C 00 6F 00 20 00 57 00 6F 00 72 00 6C 00 64 00 0D 00 0A 00
我在一个为Windows(使用Visual Studio 2008)和Mac(使用GCC)构建的程序中使用Boost C++库实现序列化.该程序std::wstring在其大约30个类中使用宽字符串().根据平台的不同,当我保存到文件(通过boost::archive::text_woarchive)时,宽字符串在输出文件中的表示方式不同.
在Windows下保存:
H*e*l*l*o* *W*o*r*l*d*!* ...
Run Code Online (Sandbox Code Playgroud)
在MacOSX下保存:
H***e***l***l***o*** ***W***o***r***l***d***!*** ...
Run Code Online (Sandbox Code Playgroud)
其中*是NULL字符.
当我尝试使用Mac版本读取在Windows下创建的文件时(反之亦然),我的程序崩溃了.
根据我的理解,到目前为止,Windows本身使用每个宽字符2个字节,而MacOSX(我猜通常使用Unix)使用4个字节.
我所遇到的可能的解决方案,比如utf8_codecvt_facet.cpp,UTF8-CPP,ICU和Dinkumware的,但我还没有看到一个例子,将与我已经有(例如,我宁愿不重写5个月系列化工作,在工作中这点):
std::wofstream ofs( "myOutputFile" );
boost::archive::text_woarchive oa( ... );
//... what do I put here? ...
oa << myMainClass;
Run Code Online (Sandbox Code Playgroud)
myMainClass 包含宽字符串和Boost智能指针到其他类,反过来,序列化.
我正在使用Visual Studio C++ 2008(Express).当我运行下面的代码时,wostream(both std::wcout和std::wfstream)在遇到第一个非ASCII字符(在这种情况下是中文)时停止输出.纯ASCII字符打印正常.但是,在调试器中,我可以看到wstrings实际上已正确填充了中文字符,并且output << ...实际上正在执行.
Visual Studio解决方案中的项目设置设置为"使用Unicode字符集".为什么std::wostream无法输出ASCII范围之外的Unicode字符?
void PrintTable(const std::vector<std::vector<std::wstring>> &table, std::wostream& output) {
for (unsigned int i=0; i < table.size(); ++i) {
for (unsigned int j=0; j < table[i].size(); ++j) {
output << table[i][j] << L"\t";
}
//output << std::endl;
}
}
void TestUnicodeSingleTableChinesePronouns() {
FileProcessor p("SingleTableChinesePronouns.docx");
FileProcessor::iterator fileIterator;
std::wofstream myFile("data.bin", std::ios::out | std::ios::binary);
for(fileIterator = p.begin(); fileIterator != p.end(); ++fileIterator) {
PrintTable(*fileIterator, myFile);
PrintTable(*fileIterator, std::wcout);
std::cout<<std::endl<<"---------------------------------------"<<std::endl;
} …Run Code Online (Sandbox Code Playgroud) 我有多字节字符串的问题.我简化了我的问题如下:
std::wstring str = L"mult?byte test string";
std::wofstream f;
f.open("F:\\dump.txt");
f << str;
f.close();
Run Code Online (Sandbox Code Playgroud)
并且转储文件的内容是:"mult"
为什么它会削减str的剩余部分,而我已经使用了wstring和wofstream?
谢谢