c++.de
Unbeantwortete Beiträge ]
Beiträge seit letztem Besuch ]
Eigene Beiträge ]
Zur normalen Ansicht ]
Startseite Forum ]
Registrieren ]
Login ]
C++ (auch C++0x und C++11) :: string und wstring ineinander umwandeln

Gehen Sie zu Seite 1, 2, 3  Weiter
Alle Beiträge auf einer Seite
NES-Spieler Mitglied Benutzerprofil Anmeldungsdatum: 27.02.2006 Beiträge: 1286
string und wstring ineinander umwandeln
14:36:54 25.12.2006
           Zitieren

Wie das unter Windows geht, weiß ich schon, doch nun würde mich mal interessieren: Wie wandle ich mit Standard-C++ einen std::string in einen std::wstring um und umgekehrt?
David_pb Mitglied Benutzerprofil Anmeldungsdatum: 09.10.2005 Beiträge: 1999

17:17:29 25.12.2006
           Zitieren

Hier wurde mal ein wunderbarer Codeschnippsel gepostet:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/* string2wstring.h */
#pragma once

 #include <string>

#include <vector>
#include <locale>
#include <functional>
#include <iostream>
 
 // Put this class in your personal toolbox...
 template<class E,
 class T = std::char_traits<E>,
 class A = std::allocator<E> >
 
 class Widen : public std::unary_function<
     const std::string&, std::basic_string<E, T, A> >
 {
     std::locale loc_;
     const std::ctype<E>* pCType_;
 
     // No copy-constructor, no assignment operator...
     Widen(const Widen&);
     Widen& operator= (const Widen&);
 
 public:
     // Constructor...
     Widen(const std::locale& loc = std::locale()) : loc_(loc)
     {
#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6.0...
         using namespace std;
         pCType_ = &_USE(loc, ctype<E> );
#else
         pCType_ = &std::use_facet<std::ctype<E> >(loc);
#endif
     }
 
     // Conversion...
     std::basic_string<E, T, A> operator() (const std::string& str) const
     {
         typename std::basic_string<E, T, A>::size_type srcLen =
             str.length();
         const char* pSrcBeg = str.c_str();
         std::vector<E> tmp(srcLen);
 
         pCType_->widen(pSrcBeg, pSrcBeg + srcLen, &tmp[0]);
         return std::basic_string<E, T, A>(&tmp[0], srcLen);
     }
 };
 
 // How to use it...
 int main()
 {
 Widen<wchar_t> to_wstring;
 std::string s = "my test string";
 std::wstring w = to_wstring(s);
 std::wcout << w << L"\n";
 }


grüße
NES-Spieler Mitglied Benutzerprofil Anmeldungsdatum: 27.02.2006 Beiträge: 1286

17:36:05 25.12.2006
           Zitieren

Das ist nicht Dein Ernst, oder? Es muß doch eine Möglichkeit geben, das ganze umzuwandeln, ohne dieses ganze Zeug da zu machen und eine komplett neue Klasse zu benutzen. Ist das wirklich derartig kompliziert?
David_pb Mitglied Benutzerprofil Anmeldungsdatum: 09.10.2005 Beiträge: 1999

17:49:11 25.12.2006
           Zitieren

Hier und da könnte man das evtl etwas vereinfachen. Aber im Grund bleibt es sich gleich. Unicode ist halt kein einfaches Thema und einfach von char zu wchar_t casten reicht eben nicht aus.
rüdiger Moderator Benutzerprofil Anmeldungsdatum: 11.07.2001 Beiträge: 23080

18:24:01 25.12.2006
           Zitieren

steht in der FAQ :rolleyes:

_________________
.
Artchi Autor Benutzerprofil Anmeldungsdatum: 16.03.2002 Beiträge: 8699

22:16:45 25.12.2006
           Zitieren

Was stört dich denn an der Methode? :confused: Nur weil du die Implementierung siehst, findest du sie nicht ernsthaft? Wer sagt dir denn, das andere Konvertierungen, wo du die Implementierungen nicht siehst, besser sind???

Leg die string2wstring.h in dein Library-Verzeichnis, und schon kannst du es wie jede andere Library einfach benutzen. Die Benutzung beschränkt sich nur auf ZWEI Zeilen!!! Und das ist nicht aufwändig. Oder glaubst du, das cout << "Hallo" auch kurz ist? Du kennst nur die Implementierung nicht. SOnst würdest du dich auch ganz schön wundern, was alles im Hintergrund passiert, bis dein Hallo in der Windows- oder Linux-Konsole erscheint.
entfrickelt Unregistrierter

22:47:08 25.12.2006
           Zitieren

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include <vector>
#include <locale>
 
std::wstring convertStringToWstring(const std::string& str)
{
    const std::ctype<wchar_t>& CType = std::use_facet<std::ctype<wchar_t> >(std::locale());
    std::vector<wchar_t> wideStringBuffer(str.length());
    CType.widen(str.data(), str.data() + str.length(), &wideStringBuffer[0]);
    return std::wstring(&wideStringBuffer[0], wideStringBuffer.size());
 }
 
int main()
{
    std::wcout << convertStringToWstring("my test string") << L"\n";
}
balduin Unregistrierter

01:48:50 26.12.2006
           Zitieren

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
using namespace std;
 
int main()
{
    wstring a(L"Hello String!");
    wstring c;
    string b;
    const char* s = (const char*)a.c_str();
    // Konvertieren von wstring nach string(a nach b)    
        for (int i = 0; *(s+i); i+=2)
                b += *(s+i);
   
    const char* y = b.c_str();
    wchar_t x;    
    // Konvertieren von string nach wstring(b nach c)
        for (int i = 0; *(y+i); i++){
                x = (wchar_t)*(y+i);
                c += x;
        }
        return 0;
}
:xmas1:
rüdiger Moderator Benutzerprofil Anmeldungsdatum: 11.07.2001 Beiträge: 23080

03:04:20 26.12.2006
           Zitieren

balduin schrieb:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
using namespace std;
 
int main()
{
    wstring a(L"Hello String!");
    wstring c;
    string b;
    const char* s = (const char*)a.c_str();
    // Konvertieren von wstring nach string(a nach b)    
        for (int i = 0; *(s+i); i+=2)
                b += *(s+i);
   
    const char* y = b.c_str();
    wchar_t x;    
    // Konvertieren von string nach wstring(b nach c)
        for (int i = 0; *(y+i); i++){
                x = (wchar_t)*(y+i);
                c += x;
        }
        return 0;
}
:xmas1:


nö! Das ist unportabler Blödsinn!

_________________
.
camper Mitglied Benutzerprofil Anmeldungsdatum: 06.08.2004 Beiträge: 6293

05:50:28 26.12.2006
           Zitieren

balduin schrieb:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
using namespace std;
 
int main()
{
    wstring a(L"Hello String!");
    wstring c;
    string b;
    const char* s = (const char*)a.c_str();
    // Konvertieren von wstring nach string(a nach b)    
        for (int i = 0; *(s+i); i+=2)
                b += *(s+i);
   
    const char* y = b.c_str();
    wchar_t x;    
    // Konvertieren von string nach wstring(b nach c)
        for (int i = 0; *(y+i); i++){
                x = (wchar_t)*(y+i);
                c += x;
        }
        return 0;
}
:xmas1:
das ist schrecklich und unportabel. Immerhin,wenn man tatsächlich weiß, dass der betreffende Wertebereich zwischen 0 und 127 liegt und es um eine Konvertierung ASCII <-> UNICODE geht (in diesem Bereich spielen locales keine Rolle), kann man das ganze vereinfachen:
C++:
1
2
3
4
5
6
7
8
9
#include <string>
using namespace std;
 
int main()
{
    wstring a(L"Hello String!");
    string b(a.begin(),a.end());
    wstring c(b.begin(),b.end());
}
Das ist in etwa, was man naiverweise erwartet. In der Praxis ist das allerdings völlig unzureichend. Das unschöne an der gezeigten Lösung von David_pb ff. ist, dass sie in jedem Falle Kopien anlegt, abwohl bei vielen (den meisten?) Implementationen string seine Daten in einem Array speichert und data() und c_str() nur pointer auf diesen Datenbereich zurückgeben. Wenn man dies voraussetzen kann, lassen sich diese Kopien vermeiden. Es dürfte allerdings keinen portablen Weg geben, dieses Verhalten bereits beim Compilieren festzustellen, während der Laufzeit allerdings ist das möglich: da op[] ein echte Referenz zurückgeben muss, brauchen wir nur &s[0] mit data() vergleichen. Sind sie gleich, können wir auf einen eigenen Vektor zum zwischenspeichern verzichten.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
template<class E, class T = std::char_traits<E>, class A = std::allocator<E> >
class Widen : public std::unary_function< const std::string&, std::basic_string<E, T, A> >
{
    const std::ctype<E>& ctype_;
    Widen(Widen&);
public:
    typedef std::basic_string<E, T, A> > str_type;
    Widen(const std::locale& loc = std::locale())
        : ctype_(std::use_facet<std::ctype<E> >(loc))
    {}
 
    // Conversion...
    str_type operator()(const std::string& str) const
    {
        // kl. Quizfrage: was machen wir, wenn string::size_type
        // und str_type::size_type verschieden sind ? :)
        typename str_type::size_type src_len = str.length();
        const char* src_data = str.data();
        if ( src_data == &str[0] )
        {
            str_type result( src_len, E() );
            const E* p = result.data();
            if ( p == &result[0] )
            {
                ctype_.widen(src_data, src_data + src_len, &result[0]);
                return result;
            }
        }
        // hier kann man noch weiter optimieren indem man etwa für
        // hinreichend kleine strings ein array auf dem stack benutzt
        std::vector<E> tmp(src_len);
        ctype_.widen(src_data, src_data + src_len, &tmp[0]);
        return str_type(&tmp[0], srcLen);
     }
};


Zuletzt bearbeitet von camper am 06:03:29 26.12.2006, insgesamt 2-mal bearbeitet
C++ (auch C++0x und C++11) :: string und wstring ineinander umwandeln

Gehen Sie zu Seite 1, 2, 3  Weiter
Alle Beiträge auf einer Seite
Auf Beitrag antworten


Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Startseite Forum ]
Zur normalen Ansicht ]
Magazin ]
Twitter Twitter ]
Facebook Facebook ]
Kontakt ]
Suchen ]
Impressum & AGB ]

Alle Rechte vorbehalten.