我在std::wstring
std::wstring tempStr = _T("F:\\Projects\\Current_자동_\\Cam.xml");
我想将此字符串存储在std::string
。
我尝试了以下代码,但结果与输入字符串
不同std::wstring tempStr = _T("F:\\Projects\\Current_자동_\\Cam.xml");
//setup converter
typedef std::codecvt_utf8_utf16 <wchar_t> convert_type;
std::wstring_convert<convert_type, wchar_t> converter;
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
std::string converted_str = converter.to_bytes( tempStr );
输入字符串中的韩语字符串将转换为"ìžë™"
。
有什么方法可以在std :: string中获得相同的字符串吗?
预期结果:
converted_str
应包含 F:\ Projects \ Current_자동_ \ Cam.xml
以下是调试的屏幕截图,显示了3种情况下的3个值(以3种方式进行转换)。但它们都没有达到预期的价值。
答案 0 :(得分:4)
您的转换代码没问题。
事实上,在UTF-8(您存储在std::string
中的字符串)中,字符자동对应于:
자 (UTF-16 0xC790) ---> UTF-8: EC 9E 90 동 (UTF-16 0xB3D9) ---> UTF-8: EB 8F 99
如果您运行以下程序,它只打印转换后的UTF-8字节,您将获得此输出:
ec 9e 90 eb 8f 99
#include <iomanip> // For std::hex
#include <iostream> // For console output
#include <string> // For STL strings
#include <codecvt> // For Unicode conversions
void print_char_hex(const char ch)
{
auto * p = reinterpret_cast<const unsigned char*>(&ch);
int i = *p;
std::cout << std::hex << i << ' ';
}
int main()
{
std::wstring utf16_str = L"\xC790\xB3D9";
// setup converter
typedef std::codecvt_utf8_utf16<wchar_t> convert_type;
std::wstring_convert<convert_type, wchar_t> converter;
// use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
std::string converted_str = converter.to_bytes( utf16_str );
// Output the converted bytes (UTF-8)
for (size_t i = 0; i < converted_str.length(); ++i)
{
print_char_hex(converted_str[i]);
}
std::cout << std::endl;
}
答案 1 :(得分:0)
我认为最好的解决方案是使用wide-char API打开文件,例如CreateFileW(...);
,因为那时你可以直接使用wide-char文件名。
如果无法做到这一点,可能不应将字符串转换为UTF8,而应转换为系统默认的ANSI代码页。 我认为这可能有用:
char out[200];
wchar_t * in = L"F:\\Projects\\Current_자동_\\Cam.xml";
WideCharToMultiByte(CP_ACP, 0, in, 100, out, 100, 0, 0);
或者可能是另一个韩国代码页:
WideCharToMultiByte(949, 0, in, 100, out, 100, 0, 0);
WideCharToMultiByte(1361, 0, in, 100, out, 100, 0, 0);
WideCharToMultiByte(10003, 0, in, 100, out, 100, 0, 0);
WideCharToMultiByte(20833, 0, in, 100, out, 100, 0, 0);
WideCharToMultiByte(20949, 0, in, 100, out, 100, 0, 0);
WideCharToMultiByte(50225, 0, in, 100, out, 100, 0, 0);
WideCharToMultiByte(50933, 0, in, 100, out, 100, 0, 0);
WideCharToMultiByte(51949, 0, in, 100, out, 100, 0, 0);
代码页ID可以在这里找到: http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
祝你好运: - )答案 2 :(得分:0)
这可以..你可以告诉因为转换回UTF16是有效的..如果你把UTF8字符串写入文件,它也会正确显示。这样,您现在有两种方法可以验证它是否有效。
// UTF16ToUTF8.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <codecvt>
std::wstring ToUTF16(const std::string &data)
{
return std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(data);
}
std::string ToUTF8(const std::wstring &data)
{
return std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(data);
}
int _tmain(int argc, _TCHAR* argv[])
{
std::wstring u16 = L"_자동_";
std::string u8 = ToUTF8(u16);
MessageBoxW(NULL, ToUTF16(u8).c_str(), L"", 0);
std::cin.get();
return 0;
}
答案 3 :(得分:0)
问题不在您的字符串转换代码中。这是典型的源文件编码问题。 Visual Studio不使用Unicode作为默认值,因此您应该自己将源文件的编码转换为UTF-8。要进行此转换,您可以使用记事本++打开文件,然后点击编码 - >转换为UTF-8
注意1:在VS2010和vs2012中,如果您将非ascii字符写入源文件,Visual Studio现在会向您发出警告并提供进行此转换。
注意2:从你使用宏_T()我预测这只针对Windows。如果您尝试使用gcc构建包含BOM的UTF-8编码源文件,则可能会出现不同的错误。在任何情况下,最好的方法是在运行时从文件中读取UTF-8编码的文本数据。
答案 4 :(得分:0)
您可以将std:string
中的UTF-8存储为常规字符序列。这是包含一些有用内容的库,例如length()
以及有关索引的所有内容,您可能希望拥有http://utfcpp.sourceforge.net/。
对于Windows控制台,您需要将代码页设置为65001
,并且将成为UTF-8。
遗憾的是,std::wstring
和整个wchar_t
事件没有指定任何特定的编码。
顺便说一句,您使用的是Managed C ++,为什么不使用.NET Framework的System::String^
?编码没有任何问题。 http://msdn.microsoft.com/ru-ru/library/system.string(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp