Pytanie brzmi: jak przekonwertować ciąg na ciąg?
Mam następny przykład:
#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;
}
wyjście z zakomentowanym wierszem to:
std::string = Hello
std::wstring = Hello
std::string = Hello
ale bez jest tylko:
std::wstring = Hello
Czy coś jest nie tak w tym przykładzie? Czy mogę wykonać konwersję jak wyżej?
EDYTOWAĆ
Nowym przykładem (biorąc pod uwagę niektóre odpowiedzi) jest
#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;
}
Dane wyjściowe to:
std::string = Hello
std::wstring = Hello
std::stringstream = 0x860283c
dlatego strumienia nie można użyć do konwersji ciągu na łańcuch.
std::wstring
co w ogóle korzystać? stackoverflow.com/questions/1049947/…Odpowiedzi:
Oto wypracowane rozwiązanie oparte na innych sugestiach:
Zwykle będzie to działać w systemie Linux, ale spowoduje problemy w systemie Windows.
źródło
std::setlocale(LC_ALL, "");
naprawdę jest potrzebny?std::wcout.imbue(locale)
powinno również wykonać zadanie i ma tę zaletę, że nie zmienia żadnego stanu globalnego.std::wstring_convert
C ++ 11 podsumowuje dużo tego hałasu.*** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***
na Linuksie 64-bit (gcc 4.7.3). Czy ktoś jeszcze tego doświadcza?Jak zauważył Cubbi w jednym z komentarzy,
std::wstring_convert
(C ++ 11) zapewnia schludne proste rozwiązanie (musisz#include
<locale>
i<codecvt>
):wcstombs
Zanim się z tym spotkałem, korzystałem z kombinacji żmudnego przydzielania / zwalniania pamięci.http://en.cppreference.com/w/cpp/locale/wstring_convert
aktualizacja (2013.11.28)
Jeden linijka może być podana jako tak (Dziękuję Guss za komentarz):
Funkcje otoki można określić w następujący sposób: (Dziękujemy ArmanSchwarz za komentarz)
Uwaga: istnieją pewne kontrowersje, czy
string
/wstring
powinny być przekazywane do funkcji jako odniesienia lub jako literały (ze względu na C ++ 11 i kompilatora aktualizacji). Decyzję pozostawię osobie wdrażającej, ale warto o tym wiedzieć.Uwaga: używam
std::codecvt_utf8
powyższego kodu, ale jeśli nie używasz UTF-8, musisz zmienić to na odpowiednie kodowanie:http://en.cppreference.com/w/cpp/header/codecvt
źródło
std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
Rozwiązanie z: http://forums.devshed.com/c-programming-42/wstring-to-string-444006.html
Uważaj, że w ogóle nie ma tu miejsca konwersja zestawu znaków. To po prostu przypisuje każdą iterację
wchar_t
dochar
- obciętej konwersji. Używa std :: string c'tor :Jak stwierdzono w komentarzach:
-
I pamiętaj, że punkty kodowe z zakresu
0x80 - 0x9F
w Win1252 nie będą działać. Obejmuje to€
,œ
,ž
,Ÿ
, ...źródło
Zamiast uwzględniać ustawienia regionalne i wszystkie inne wymyślne rzeczy, jeśli znasz FACT, łańcuch można konwertować, po prostu zrób to:
Przykład na żywo tutaj
źródło
Wydaje mi się, że oficjalnym sposobem są wciąż szczegółowe
codecvt
aspekty (potrzebujesz jakiegoś tłumaczenia zależnego od lokalizacji), jak wlub coś w tym rodzaju, nie mam wokół siebie działającego kodu. Ale nie jestem pewien, ile osób korzysta obecnie z tej maszyny i ilu po prostu prosi o wskaźniki do pamięci i pozwala ICU lub innej bibliotece obsłużyć krwawe szczegóły.
źródło
Istnieją dwa problemy z kodem:
Konwersja w
const std::string s( ws.begin(), ws.end() );
nie jest wymagana do poprawnego odwzorowania szerokich znaków na ich wąski odpowiednik. Najprawdopodobniej każda szeroka postać będzie po prostu rzutem na typchar
.Rozwiązanie tego problemu jest już podane w odpowiedzi przez kem i obejmuje
narrow
funkcjęctype
aspektu ustawień regionalnych .Piszesz wyjście zarówno
std::cout
istd::wcout
w tym samym programie. Zarównocout
iwcout
są związane z tym samym strumieniem (stdout
) i wyniki z użyciem takiego samego strumienia, zarówno w postaci strumienia bajtowo (cocout
ma miejsce) i szerokości zorientowanej strumień (jakwcout
nie) nie jest zdefiniowana.Najlepszą opcją jest unikanie miksowania wąskiego i szerokiego wyjścia do tego samego (podstawowego) strumienia. W przypadku
stdout
/cout
/wcout
możesz spróbować zmienić orientacjęstdout
podczas przełączania między szerokim a wąskim wyjściem (lub odwrotnie):źródło
Ten kod ma dwie formy do konwersji std :: string na std :: wstring i std :: wstring na std :: string. Jeśli zanegujesz # jeśli zdefiniowano WIN32, otrzymasz ten sam wynik.
1. std :: string na std :: wstring
• MultiByteToWideChar WinAPI
• _mbstowcs_s_l
2. std :: wstring do std :: string
• WideCharToMultiByte WinAPI
• _wcstombs_s_l
3. W systemie Windows musisz wydrukować Unicode, używając WinAPI.
• WriteConsole
4. W programie głównym.
5. Wreszcie potrzebujesz potężnej i pełnej obsługi znaków Unicode w konsoli. Polecam ConEmu i ustawiam jako domyślny terminal w systemie Windows . Musisz podłączyć Visual Studio do ConEmu. Pamiętaj, że plik exe programu Visual Studio to devenv.exe
Wynik
źródło
Równie dobrze możesz po prostu użyć wąskiej metody aspektu ctype bezpośrednio:
źródło
W momencie pisania tej odpowiedzi wyszukiwarka Google numer jeden „konwersja ciągu znaków” wylądowałaby na tej stronie. Moja odpowiedź pokazuje, jak przekonwertować ciąg znaków na wstring, chociaż to nie jest właściwe pytanie i prawdopodobnie powinienem usunąć tę odpowiedź, ale jest to uważane za złą formę. Możesz przejść do odpowiedzi StackOverflow , która jest teraz wyżej w rankingu niż ta strona.
Oto sposób na połączenie ciągów strun, strun i mieszanych stałych strun z strunami. Użyj klasy wstringstream.
źródło
Oprócz zwykłej konwersji typów, powinieneś także być świadomy faktycznego formatu łańcucha.
Podczas kompilacji dla zestawu znaków wielobajtowych Visual Studio i Win API zakłada UTF8 (w rzeczywistości kodowanie Windows, czyli Windows-28591 ).
Podczas kompilacji dla zestawu znaków Unicode Visual Studio i Win API zakłada UTF16.
Musisz więc przekonwertować ciąg z formatu UTF16 na format UTF8, a nie tylko konwertować na std :: string.
Stanie się to konieczne podczas pracy z formatami wieloznakowymi, takimi jak niektóre języki inne niż łacińskie.
Chodzi o to, aby zdecydować, że
std::wstring
zawsze reprezentuje UTF16 .I
std::string
zawsze reprezentuje UTF8 .Kompilator tego nie wymusza, jest to raczej dobra polityka. Zwróć uwagę na przedrostki ciągu, których używam do zdefiniowania UTF16 ( L ) i UTF8 ( u8 ).
Aby przekonwertować dwa typy, powinieneś użyć: std :: codecvt_utf8_utf16 <wchar_t>
źródło
W moim przypadku muszę użyć znaku wielobajtowego (MBCS) i chcę użyć std :: string i std :: wstring. I nie można używać c ++ 11. Więc używam mbstowcs i wcstombs.
Wykonuję tę samą funkcję za pomocą new, delete [], ale jest to wolniejsze niż to.
Może to pomóc w jaki sposób: Konwersja między różnymi typami ciągów
EDYTOWAĆ
Jednak w przypadku konwersji na łańcuch i łańcuch źródłowy to nie alfabet i łańcuch wielobajtowy, to nie działa. Więc zmieniam wcstombs na WideCharToMultiByte.
EDYCJA, aby użyć „MultiByteToWideChar” zamiast „wcstombs”
źródło
wcstombs()
.To rozwiązanie jest zainspirowane rozwiązaniem dk123 , ale korzysta z zależnego od regionu aspektu codecvt. Wynik jest w postaci łańcucha zakodowanego w ustawieniach regionalnych zamiast w UTF-8 (jeśli nie jest ustawiony jako ustawienia regionalne):
Szukałem tego, ale nie mogę go znaleźć. W końcu odkryłem, że mogę uzyskać właściwy aspekt,
std::locale
używającstd::use_facet()
funkcji o właściwej nazwie typu. Mam nadzieję że to pomoże.źródło
W przypadku, gdy ktoś jest zainteresowany: Potrzebowałem klasy, które mogą być używane zamiennie, gdziekolwiek albo
string
czywstring
był oczekiwany. Następujące klasyconvertible_string
, w oparciu o rozwiązanie dk123 męska może być zainicjowany albo zstring
,char const*
,wstring
lubwchar_t const*
mogą być przypisane do lub pośrednio przez konwertowana nastring
lubwstring
(a więc mogą być przekazywane do funkcji, które mają zarówno).źródło
std::wstring
w klasie, niż przechowywaćstd::string
i wykonać konwersję do,std::wstring
gdy jest to potrzebne, aby uzyskaćstd::wstring
. Ponieważstd::wstring
jest nieco szybszystd::string
i lepiej kompatybilny. Nawet zużywa więcej pamięci niżstd::string
.źródło
Używam poniżej, aby przekonwertować ciąg na ciąg.
źródło
<string>
) i definicjiWideCharToMultiByte()
- czy to jakieś opakowaniestd::wctomb()
?źródło