Nếu tôi có UTF-8 std::string
làm cách nào để chuyển đổi nó sang UTF-16 std::wstring
? Thực ra, tôi muốn so sánh hai từ tiếng Ba Tư.Làm thế nào để chuyển đổi UTF-8 std :: chuỗi thành UTF-16 std :: wstring?
Trả lời
Dưới đây là một số mã. Chỉ được thử nghiệm nhẹ và có thể có một số cải tiến. Gọi hàm này để chuyển đổi chuỗi UTF-8 thành chuỗi ký tự UTF-16. Nếu nó cho rằng chuỗi đầu vào không phải là UTF-8 thì nó sẽ ném một ngoại lệ, ngược lại nó trả về chuỗi ký tự UTF-16 tương đương.
std::wstring utf8_to_utf16(const std::string& utf8)
{
std::vector<unsigned long> unicode;
size_t i = 0;
while (i < utf8.size())
{
unsigned long uni;
size_t todo;
bool error = false;
unsigned char ch = utf8[i++];
if (ch <= 0x7F)
{
uni = ch;
todo = 0;
}
else if (ch <= 0xBF)
{
throw std::logic_error("not a UTF-8 string");
}
else if (ch <= 0xDF)
{
uni = ch&0x1F;
todo = 1;
}
else if (ch <= 0xEF)
{
uni = ch&0x0F;
todo = 2;
}
else if (ch <= 0xF7)
{
uni = ch&0x07;
todo = 3;
}
else
{
throw std::logic_error("not a UTF-8 string");
}
for (size_t j = 0; j < todo; ++j)
{
if (i == utf8.size())
throw std::logic_error("not a UTF-8 string");
unsigned char ch = utf8[i++];
if (ch < 0x80 || ch > 0xBF)
throw std::logic_error("not a UTF-8 string");
uni <<= 6;
uni += ch & 0x3F;
}
if (uni >= 0xD800 && uni <= 0xDFFF)
throw std::logic_error("not a UTF-8 string");
if (uni > 0x10FFFF)
throw std::logic_error("not a UTF-8 string");
unicode.push_back(uni);
}
std::wstring utf16;
for (size_t i = 0; i < unicode.size(); ++i)
{
unsigned long uni = unicode[i];
if (uni <= 0xFFFF)
{
utf16 += (wchar_t)uni;
}
else
{
uni -= 0x10000;
utf16 += (wchar_t)((uni >> 10) + 0xD800);
utf16 += (wchar_t)((uni & 0x3FF) + 0xDC00);
}
}
return utf16;
}
cảm ơn bạn! cảm ơn bạn! nó đã làm việc ... Tôi không thể tin được :) cảm ơn bạn đã dành thời gian của bạn john – aliakbarian
Thật vui vì nó đã giúp ích. Nó thực sự chỉ là vấn đề đặt câu hỏi đúng. Có rất nhiều kiến thức trên diễn đàn này, nhưng người mới thường không thể truy cập kiến thức đó bởi vì họ không biết phải hỏi gì. – john
cảm ơn bạn một lần nữa! :-) – aliakbarian
Có một số liên quan Q & A here và here đáng để đọc.
Về cơ bản, bạn cần phải chuyển đổi chuỗi thành định dạng chung - tùy chọn của tôi luôn chuyển đổi thành UTF-8, nhưng số dặm của bạn có thể cảnh giác.
Đã có rất nhiều phần mềm được viết để thực hiện việc chuyển đổi - chuyển đổi là straigth chuyển tiếp và có thể được viết trong một vài giờ - tuy nhiên tại sao không pick up something already done such as the UTF-8 CPP
Nếu bạn chỉ sử dụng Windows: http://msdn.microsoft.com/en-us/library/dd319072(v=VS.85).aspx. Nếu không, hãy sử dụng thư viện di động. –
Trang này cũng có vẻ hữu ích: http://www.codeproject.com/KB/string/UtfConverter.aspx
Trong phần bình luận của trang đó, cũng có một số gợi ý thú vị cho nhiệm vụ này như:
// Get en ASCII std::string from anywhere
std::string sLogLevelA = "Hello ASCII-world!";
std::wstringstream ws;
ws << sLogLevelA.c_str();
std::wstring sLogLevel = ws.str();
Hoặc
// To std::string:
str.assign(ws.begin(), ws.end());
// To std::wstring
ws.assign(str.begin(), str.end());
Mặc dù tôi không chắc chắn về tính hợp lệ của các cách tiếp cận này ...
Đây là cách bạn làm điều đó với C++ 11:
std::string str = "your string in utf8";
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>> converter;
std::wstring wstr = converter.from_bytes(str);
Và đây là những tiêu đề bạn cần:
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
Một ví dụ hoàn chỉnh hơn có sẵn ở đây: http://en.cppreference.com/w/cpp/locale/wstring_convert/from_bytes
Câu trả lời hay, cảm ơn! ... nhưng hãy làm theo ví dụ tại cppreference.com. 'wchar_t' không phải là kiểu 16 bit trên các hệ điều hành khác với Windows. Bạn cần sử dụng 'char16_t' để thay thế. –
@CrisLuengo cảm ơn! Tôi đã cập nhật câu trả lời để sử dụng 'char16_t'. –
Không hoạt động với g ++ 6.2 hoặc clang ++ 3.8 trên lubuntu 16.04 –
- 1. Làm thế nào để chuyển đổi mảng utf16 ushort thành chuỗi utf8 std ::?
- 2. Cách tốt nhất để chuyển đổi std :: wstring thành QString
- 3. Làm thế nào để chuyển đổi CString và :: std :: string :: std :: wstring với nhau?
- 4. Làm thế nào để chuyển đổi std :: chuỗi để LPCSTR?
- 5. Không thể chuyển std :: wstring qua DLL
- 6. Làm thế nào để chuyển đổi std :: string thành NSString?
- 7. std :: chuỗi, wstring, u16/32 làm rõ chuỗi
- 8. Chuyển đổi từ chuỗi std :: thành bool
- 9. chuyển đổi int thành wstring
- 10. xcode std :: wcout với wchar_t hoặc std :: wstring!
- 11. Làm cách nào để chuyển đổi chuỗi thành UTF8?
- 12. Chuyển đổi std :: string thành std :: vector <char>
- 13. chuyển đổi Rcpp :: CharacterVector thành std :: string
- 14. Chuyển đổi một void * thành std :: string
- 15. Chuyển đổi chuỗi C thành kiểu C++ std :: string
- 16. Làm thế nào để chuyển đổi char * sang std :: vector?
- 17. Chuyển đổi uint64_t thành std :: string
- 18. Chuyển đổi std :: string thành số nguyên
- 19. Làm cách nào để chuyển đổi chuỗi std :: thành tăng :: gregorian :: date?
- 20. Cách khởi tạo và in std :: wstring?
- 21. So sánh chuỗi. Làm thế nào bạn có thể so sánh chuỗi với std :: wstring? WRT strcmp
- 22. chuyển đổi std: vector thành NSArray
- 23. Chuyển đổi QString thành std :: string
- 24. chuyển đổi std :: string thành basic_ostream?
- 25. C-Style strings to std :: làm rõ chuỗi chuyển đổi
- 26. Làm thế nào tôi có thể nhận được kích thước byte của std :: wstring?
- 27. Chuyển đổi đối tượng để std :: unique_ptr
- 28. Làm thế nào để chuyển đổi unsigned char * thành std :: string in C++?
- 29. Làm thế nào để chuyển đổi std :: chrono :: time_point để std :: tm mà không sử dụng time_t?
- 30. Làm thế nào để chèn một cặp std :: cặp bên trong một std :: cặp?
Xem http://stackoverflow.com/questions/148403/utf8-to-from-wide-char-conversion-in-stl trong số những người khác. –
có thể trùng lặp của [làm thế nào tôi có thể so sánh chuỗi utf8 chẳng hạn như từ tiếng Ba Tư trong c + +?] (Http://stackoverflow.com/questions/7141417/how-can-i-compare-utf8-string-such-as-persian- word-in-c) hoặc [this] (http://stackoverflow.com/questions/7141260/compare-stdwstring-and-stdstring). –