Pertanyaannya adalah bagaimana cara mengkonversi wstring ke string?
Saya punya contoh berikut:
#include <string>
#include <iostream>
int main()
{
std::wstring ws = L"Hello";
std::string s( ws.begin(), ws.end() );
//std::cout <<"std::string = "<<s<<std::endl;
std::wcout<<"std::wstring = "<<ws<<std::endl;
std::cout <<"std::string = "<<s<<std::endl;
}
output dengan garis komentar adalah:
std::string = Hello
std::wstring = Hello
std::string = Hello
tetapi tanpa hanya:
std::wstring = Hello
Apakah ada yang salah dalam contoh? Bisakah saya melakukan konversi seperti di atas?
EDIT
Contoh baru (dengan mempertimbangkan beberapa jawaban) adalah
#include <string>
#include <iostream>
#include <sstream>
#include <locale>
int main()
{
setlocale(LC_CTYPE, "");
const std::wstring ws = L"Hello";
const std::string s( ws.begin(), ws.end() );
std::cout<<"std::string = "<<s<<std::endl;
std::wcout<<"std::wstring = "<<ws<<std::endl;
std::stringstream ss;
ss << ws.c_str();
std::cout<<"std::stringstream = "<<ss.str()<<std::endl;
}
Outputnya adalah:
std::string = Hello
std::wstring = Hello
std::stringstream = 0x860283c
oleh karena itu stringstream tidak dapat digunakan untuk mengubah wstring menjadi string.
std::wstring
sama sekali? stackoverflow.com/questions/1049947/…Jawaban:
Berikut adalah solusi yang berhasil berdasarkan saran lainnya:
Ini biasanya bekerja untuk Linux, tetapi akan menimbulkan masalah pada Windows.
sumber
std::setlocale(LC_ALL, "");
benar - benar dibutuhkan?std::wcout.imbue(locale)
harus melakukan pekerjaan itu juga, dan memiliki manfaat bahwa itu tidak mengubah keadaan global.std::wstring_convert
dari C ++ 11 merangkum banyak kebisingan ini.*** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***
di linux 64-bit (gcc 4.7.3). Adakah yang mengalami hal ini?Seperti yang ditunjukkan Cubbi dalam salah satu komentar,
std::wstring_convert
(C ++ 11) memberikan solusi sederhana yang rapi (Anda perlu#include
<locale>
dan<codecvt>
):Saya menggunakan kombinasi dari
wcstombs
dan alokasi / dealokasi memori yang membosankan sebelum saya menemukan ini.http://en.cppreference.com/w/cpp/locale/wstring_convert
pembaruan (2013.11.28)
Satu liner dapat dinyatakan demikian (Terima kasih, Guss atas komentar Anda):
Fungsi Wrapper dapat dinyatakan sebagai: (Terima kasih ArmanSchwarz atas komentar Anda)
Catatan: ada beberapa kontroversi tentang apakah
string
/wstring
harus diteruskan ke fungsi sebagai referensi atau sebagai literal (karena C ++ 11 dan pembaruan kompiler). Saya akan menyerahkan keputusan kepada orang yang menerapkan, tetapi perlu diketahui.Catatan: Saya menggunakan
std::codecvt_utf8
dalam kode di atas, tetapi jika Anda tidak menggunakan UTF-8 Anda harus mengubahnya ke pengkodean yang sesuai yang Anda gunakan:http://en.cppreference.com/w/cpp/header/codecvt
sumber
std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
Solusi dari: http://forums.devshed.com/c-programming-42/wstring-to-string-444006.html
Berhati - hatilah karena tidak ada konversi rangkaian karakter yang terjadi di sini. Apa yang dilakukan adalah hanya untuk menetapkan setiap iterasi
wchar_t
kechar
- konversi terpotong. Ia menggunakan std :: string c'tor :Sebagaimana dinyatakan dalam komentar:
-
Dan perhatikan bahwa titik kode dalam kisaran
0x80 - 0x9F
di Win1252 tidak akan berfungsi. Ini termasuk€
,œ
,ž
,Ÿ
, ...sumber
Alih-alih menyertakan lokal dan semua barang mewah itu, jika Anda tahu FACT string Anda dapat dikonversi, lakukan saja ini:
Contoh langsung di sini
sumber
Saya percaya bahwa cara resmi masih berlaku untuk semua
codecvt
aspek (Anda perlu semacam terjemahan sadar-lokal), seperti dalamatau sesuatu seperti itu, saya tidak memiliki kode kerja di sekitar. Tapi saya tidak yakin berapa banyak orang saat ini menggunakan mesin itu dan berapa banyak yang hanya meminta pointer ke memori dan membiarkan ICU atau perpustakaan lain menangani detail berdarah.
sumber
Ada dua masalah dengan kode:
Konversi dalam
const std::string s( ws.begin(), ws.end() );
tidak diperlukan untuk memetakan karakter lebar dengan benar ke rekan sempitnya. Kemungkinan besar, setiap karakter lebar hanya akan typecast kechar
.Resolusi untuk masalah ini sudah diberikan dalam jawaban oleh kem dan melibatkan
narrow
fungsi dari sisi lokalctype
.Anda menulis keluaran untuk keduanya
std::cout
danstd::wcout
dalam program yang sama. Keduanyacout
danwcout
dikaitkan dengan aliran yang sama (stdout
) dan hasil menggunakan aliran yang sama baik sebagai aliran berorientasi byte (seperticout
halnya) dan aliran berorientasi lebar (sepertiwcout
halnya) tidak didefinisikan.Pilihan terbaik adalah menghindari pencampuran output sempit dan lebar ke aliran (mendasar) yang sama. Untuk
stdout
/cout
/wcout
, Anda dapat mencoba mengalihkan orientasistdout
ketika beralih antara output lebar dan sempit (atau sebaliknya):sumber
Kode ini memiliki dua bentuk untuk mengkonversi std :: string ke std :: wstring dan std :: wstring ke std :: string. Jika Anda meniadakan # jika didefinisikan WIN32, Anda mendapatkan hasil yang sama.
1. std :: string ke std :: wstring
• MultiByteToWideChar WinAPI
• _mbstowcs_s_l
2. std :: wstring ke std :: string
• WideCharToMultiByte WinAPI
• _wcstombs_s_l
3. Pada windows Anda perlu mencetak unicode, menggunakan WinAPI.
• WriteConsole
4. Di program utama.
5. Terakhir, Anda memerlukan dukungan yang kuat dan lengkap untuk karakter unicode di konsol. Saya merekomendasikan ConEmu dan ditetapkan sebagai terminal default pada Windows . Anda perlu menghubungkan Visual Studio ke ConEmu. Ingat bahwa file exe Visual Studio adalah devenv.exe
Hasil
sumber
Anda mungkin juga cukup menggunakan metode sempit ctype facet secara langsung:
sumber
Pada saat menulis jawaban ini, pencarian google nomor satu untuk "convert string wstring" akan mendaratkan Anda di halaman ini. Jawaban saya menunjukkan bagaimana mengkonversi string ke wstring, meskipun ini BUKAN pertanyaan yang sebenarnya, dan saya mungkin harus menghapus jawaban ini, tetapi itu dianggap bentuk yang buruk. Anda mungkin ingin melompat ke jawaban StackOverflow ini , yang sekarang berperingkat lebih tinggi dari halaman ini.
Berikut adalah cara untuk menggabungkan konstanta string, wstring dan string campuran ke wstring. Gunakan kelas wstringstream.
sumber
Selain hanya mengonversi jenis, Anda juga harus sadar tentang format aktual string.
Ketika mengkompilasi untuk Multi-byte Character set Visual Studio dan Win API mengasumsikan UTF8 (Sebenarnya windows encoding yang merupakan Windows-28591 ).
Saat mengkompilasi untuk Unicode Character set Visual studio dan Win API mengasumsikan UTF16.
Jadi, Anda harus mengonversi string dari format UTF16 ke UTF8 juga, dan tidak hanya mengonversi ke std :: string.
Ini akan menjadi perlu ketika bekerja dengan format multi-karakter seperti beberapa bahasa non-latin.
Idenya adalah untuk memutuskan yang
std::wstring
selalu mewakili UTF16 .Dan
std::string
selalu mewakili UTF8 .Ini tidak diberlakukan oleh kompiler, ini lebih merupakan kebijakan yang baik untuk dimiliki. Perhatikan awalan string yang saya gunakan untuk mendefinisikan UTF16 ( L ) dan UTF8 ( u8 ).
Untuk mengkonversi antara 2 jenis, Anda harus menggunakan: std :: codecvt_utf8_utf16 <wchar_t>
sumber
Dalam kasus saya, saya harus menggunakan karakter multibyte (MBCS), dan saya ingin menggunakan std :: string dan std :: wstring. Dan tidak bisa menggunakan c ++ 11. Jadi saya menggunakan mbstowcs dan wcstombs.
Saya membuat fungsi yang sama dengan menggunakan baru, hapus [], tetapi lebih lambat dari ini.
Ini dapat membantu Cara: Mengkonversi Berbagai Jenis String
EDIT
Namun, dalam kasus konversi ke string wstring dan sumber tidak ada alfabet dan string multi byte, itu tidak berfungsi. Jadi saya mengubah wcstombs menjadi WideCharToMultiByte.
EDIT untuk menggunakan 'MultiByteToWideChar' alih-alih 'wcstombs'
sumber
wcstombs()
.Solusi ini terinspirasi dari solusi dk123 , tetapi menggunakan aspek codecvt yang bergantung pada lokal. Hasilnya dalam string yang disandikan lokal bukannya UTF-8 (jika tidak ditetapkan sebagai lokal):
Saya sedang mencarinya, tetapi saya tidak dapat menemukannya. Akhirnya saya menemukan bahwa saya bisa mendapatkan aspek yang tepat dari
std::locale
menggunakanstd::use_facet()
fungsi dengan nama ketik yang tepat. Semoga ini membantu.sumber
Jika ada orang lain yang tertarik: Saya membutuhkan kelas yang dapat digunakan secara bergantian di mana pun
string
atauwstring
diharapkan. Kelas berikutconvertible_string
, berdasarkan solusi dk123 ini , dapat diinisialisasi dengan baikstring
,char const*
,wstring
atauwchar_t const*
dan dapat ditugaskan oleh atau implisit dikonversi ke salah satustring
atauwstring
(sehingga dapat diteruskan ke dalam sebuah fungsi yang mengambil baik).sumber
std::wstring
di kelas, daripada menyimpanstd::string
dan melakukan konversistd::wstring
ketika diperlukan untuk mendapatkanstd::wstring
. Karenastd::wstring
agak lebih cepat daripadastd::string
dan lebih kompatibel. Bahkan itu menghabiskan lebih banyak memori daripadastd::string
.sumber
Saya menggunakan di bawah ini untuk mengkonversi wstring ke string.
sumber
<string>
) dan definisi untukWideCharToMultiByte()
- apakah ada beberapa pembungkusstd::wctomb()
?sumber