CHAR konvertieren in WCHAR



  • MultiByteToWideChar ist doch gar nicht so schlecht:

    #include <windows.h>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    wstring charToWide(string in)
    {
    	WCHAR *wideString = new WCHAR[in.size() + 1];
    
    	MultiByteToWideChar(CP_ACP, 0, in.c_str(), in.size() + 1, wideString, in.size() + 1);
    
    	wstring wideVersion(wideString);
    
    	delete [] wideString;
    
    	return wideVersion;
    }
    
    int main()
    {
    	string charString;
    
    	cout << "Gib einen String ein:\n";
    
    	getline(cin, charString);
    	cout << "char - " << charString.c_str() << '\n';
    
    	wstring wideString = charToWide(charString);
    
    	wcout << "wchar - " << wideString.c_str() << '\n';
    }
    


  • Was solls denn sein, C oder C++ (C/C++-Lösungen gibt es natürlich auch 🤡 )?
    Mit MultiByteToWideChar (C)

    wchar_t* ToWString(const char* src)
    {
        size_t len = strlen(src);
        wchar_t* dst = malloc((len+1)*sizeof(wchar_t));
        if(dst)
        {
            if(!MultiByteToWideChar(CP_ACP, 0, src, len, dst, len))
            {
                free(dst);
                dst = 0;
            }
        }
        return dst;
    }
    

    Nicht so schön ist hierbei, dass der Speicher manuell freigegeben werden muss.
    Vielleicht doch eher C++ (auch mit obiger Funktion):

    std::wstring ToWString(const char* src)
    {
    	size_t len = strlen(src);
    	std::vector<wchar_t> dst(len+1);
    	if(!MultiByteToWideChar(CP_ACP, 0, src, len, &dst[0], len))
    	{
    		throw std::runtime_error("MultiByteToWideChar failed");
    	}
    	return &dst[0];
    }
    

    Ansonsten (ohne MultiByteToWideChar)

    use_facet<ctype<wchar_t> > (cout.getloc()).widen(src, src+len, &dst[0]);
    


  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum C (C89 und C99) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Danke für die Antworten Leute,
    werds morgen mal versuchen, für meinen Code umzubauen.

    Ich hoff, ich bring was zusammen - ansonsten sag ich euch definitiv wieder Bescheid und nerve 🙂 😉



  • Hi,
    bei deinem Vorschlag treten leider folgende Fehler auf
    (ich verwende den Digital Mars C/C++ Compiler):

    using namespace std;
    ^
    char_to_wchar_001.c(5) : Error: undefined identifier 'std'
    wstring charToWide(string in)
    ^
    char_to_wchar_001.c(7) : Error: missing decl-specifier-seq for declaration of 'wstring'
    MultiByteToWideChar(CP_ACP, 0, in.c_str(), in.size() + 1, wideString, in.size() + 1);
    ^
    char_to_wchar_001.c(11) : Error: 'MultiByteToWideChar' previously declared as something else
    It was declared as: int __import (__import std func)(unsigned ,unsigned long ,char const *,int ,wchar_t *,int )
    It is now declared: int
    wstring wideVersion(wideString);
    ^
    char_to_wchar_001.c(13) : Error: 'wstring' is not in function parameter list
    delete [] wideString;
    ^
    char_to_wchar_001.c(15) : Error: '=', ';' or ',' expected
    Fatal error: too many errors
    --- errorlevel 1



  • Dein Dateiname char_to_wchar_001.c lässt vermuten, dass Du das nicht als c++ sondern als c - Programm übersetzen lässt.
    Ich habe c++ genommen, weil Du in Deinem Beispiel cout benutzt hattest.



  • Hast Du #include <string> gemacht?



  • ahaaaa 🤡
    Kommando zurück.

    Habs nun mit Belli's Code versucht und bin zu folgender Erkenntnis gekommen:
    Der Digital Mars C/C++ Compiler benötigt für den <iostream> Folgendes:
    To use <iostream> and other STL code, download STLport 4.5.3 as well. Be sure and use the switch:
    -I\dm\stlport\stlport

    so that the compiler can find <iostream>.

    jetzt tritt mal beim Compilieren kein Fehler mehr auf....mal sehn, ob ichs nun zusammenbringe 🙄



  • 😞 😞 *weeeein* nun hätt ich die Konvertierung doch mit eurer Hilfe bewältigt und dann hab ich das Problem, dass ich definitiv C und nicht C++ Code benötige, damit ich im Anschluß dieses mit einem weitaus komplexeren C Script kombinieren kann.

    Könnt ihr mir bitte helfen, die derzeitige Fassung von C++ auf C umzuschreiben?

    derzeitiger Code:

    #include <stdio.h>
    #include <windows.h>
    #include <stdlib.h>
    #include <iostream>
    #include <string>

    using namespace std;

    wstring charToWide(string in)
    {
    WCHAR *KeyNameBuffer = new WCHAR[in.size() + 1];
    MultiByteToWideChar(CP_ACP, 0, in.c_str(), in.size() + 1, KeyNameBuffer, in.size() + 1);
    wstring wideVersion(KeyNameBuffer);
    delete [] KeyNameBuffer;
    return wideVersion;
    }

    WCHAR KeyNameBuffer[] = L"";
    char Teilschluessel[] = { "\\Registry\\Machine\\SOFTWARE\\Wow6432Node\\Classes\\CLSID\" };
    char Gesamtschluessel[] = { "" };

    int main ()
    {
    char Schluesselname[40];

    printf("Bitte geben Sie den Registryschluessel ein: \n");
    gets(Schluesselname);
    printf("\n\n---------------------------------------------------\n");
    printf("Schluesselname: %s\n",Schluesselname);
    printf("Teilregistrierungsschluessel: %s\n",Teilschluessel);
    strcpy (Gesamtschluessel, Teilschluessel);
    strcat (Gesamtschluessel, Schluesselname);
    printf("Gesamtregistrierungsschluessel: %s\n",Gesamtschluessel);
    wprintf(L"derzeitiger KeyNameBuffer: %s\n",KeyNameBuffer);

    wstring KeyNameBuffer = charToWide(Gesamtschluessel);
    // wcout << "wchar - " << KeyNameBuffer.c_str() << '\n';

    wprintf(L"\n\nWCHAR: %s\n",KeyNameBuffer.c_str());

    printf("--------------------------------------------------- \n");

    wprintf(L"\n\nWCHAR: %s\n",KeyNameBuffer);

    system("PAUSE");
    return 0;
    }



  • WCHAR* charToWide(const char* in)
    {
    WCHAR *KeyNameBuffer = malloc((strlen(in) + 1) * sizeof(WCHAR));

    MultiByteToWideChar(CP_ACP, 0, in, strlen(in) + 1, KeyNameBuffer, strlen(in) + 1);

    return KeyNameBuffer;
    }

    Nun musst Du allerdings darauf achten, an geeigneter Stelle den reservierten Speicher wieder freizugeben!



  • Hi Belli,

    kommt zwar kein Error beim Compilieren, allerdings erfolgt auch nur eine leere Ausgabe, wenn ich den WCHAR in der vorvorvorletzten Zeile ausgeben will.

    #include <stdio.h>
    #include <windows.h>
    #include <stdlib.h>
    #include "reghide.h"

    WCHAR* charToWide(const char* in)
    {
    WCHAR *KeyNameBuffer = malloc((strlen(in) + 1) * sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, in, strlen(in) + 1, KeyNameBuffer, strlen(in) + 1);
    return KeyNameBuffer;
    }

    WCHAR KeyNameBuffer[] = L"";
    char Teilschluessel[] = { "\\Registry\\Machine\\SOFTWARE\\Wow6432Node\\Classes\\CLSID\" };
    char Gesamtschluessel[] = { "" };

    int main ()
    {
    char Schluesselname[40];

    printf("Bitte geben Sie den Registryschluessel ein: \n");
    gets(Schluesselname);
    printf("\n\n---------------------------------------------------\n");
    printf("Schluesselname: %s\n",Schluesselname);
    printf("Teilregistrierungsschluessel: %s\n",Teilschluessel);
    strcpy (Gesamtschluessel, Teilschluessel);
    strcat (Gesamtschluessel, Schluesselname);
    printf("Gesamtregistrierungsschluessel: %s\n",Gesamtschluessel);
    wprintf(L"\n\nWCHAR: %s\n",KeyNameBuffer);
    printf("--------------------------------------------------- \n");
    system("PAUSE");
    return 0;
    }



  • Schon mal daran gedacht, dass du auch Speicherplatz für deine Texte brauchst.

    char Gesamtschluessel[] = { "" };
    

    belegt Speicher für einen String der Länge 0.
    Der wird auch nicht automatisch vergrößert.
    strcpy() und strcat() verlassen sich aber darauf, dass im Zielstring genug Platz ist.

    Und bitte nutze die C/C++ Tags, damit es farbig und bunt wird.
    Text markieren und den C/C++ Button undter den 🙂 😃 anklicken. Danke.



  • Hi DirkB,

    okay - danke für die Info. Leider bin ich wie gesagt ein blutiger Anfänger und würde die Funktionsweise jedoch dringend benötigen.
    Ich habe jedoch nun für meine Variablen Speicher definiert (beispielsweise [300]), das ändert jedoch nichts am derzeitigen Problem - es wird nichts ausgegeben...



  • okay also oben hab ich natürlich was falsch gemacht - trotzalledem kommt es bei folgendem Code noch immer zu keiner Ausgabe:

    #include <stdio.h>
    #include <windows.h>
    #include <stdlib.h>
    #include "reghide.h"
    
    WCHAR* charToWide(const char* in)
    {
    WCHAR *KeyNameBuffer = malloc((strlen(in) + 1) * sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, in, strlen(in) + 1, KeyNameBuffer, strlen(in) + 1);
    return KeyNameBuffer;
    }
    
    WCHAR KeyNameBuffer[] = L"";
    char Teilschluessel[] = { "\\Registry\\Machine\\SOFTWARE\\Wow6432Node\\Classes\\CLSID\" };
    char Gesamtschluessel[] = { "" };
    
    int main ()
    {
    char Schluesselname[40];
    
    printf("Bitte geben Sie den Registryschluessel ein: \n");
    gets(Schluesselname);
    printf("\n\n---------------------------------------------------\n");
    printf("Schluesselname: %s\n",Schluesselname);
    printf("Teilregistrierungsschluessel: %s\n",Teilschluessel);
    strcpy (Gesamtschluessel, Teilschluessel);
    strcat (Gesamtschluessel, Schluesselname);
    printf("Gesamtregistrierungsschluessel: %s\n",Gesamtschluessel);
    wprintf(L"\n\nWCHAR: %s\n",KeyNameBuffer);
    printf("--------------------------------------------------- \n");
    system("PAUSE");
    return 0;
    }
    


  • Bitte um Hilfe! 😞

    #include <stdio.h>
    #include <windows.h>
    #include <stdlib.h>
    #include "reghide.h"
    
    WCHAR* charToWide(const char* Gesamtschluessel)
    {
    WCHAR *KeyNameBuffer = malloc((strlen(Gesamtschluessel) + 1) * sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, Gesamtschluessel, strlen(Gesamtschluessel) + 1, KeyNameBuffer, strlen(Gesamtschluessel) + 1);
    return KeyNameBuffer;
    } 
    
    WCHAR KeyNameBuffer[] = L"";
    char Teilschluessel[] = { "\\Registry\\Machine\\SOFTWARE\\Wow6432Node\\Classes\\CLSID\\" };
    char Gesamtschluessel[] = { "" };
    
    int main ()
    {
    char Schluesselname[40];
    
    printf("Bitte geben Sie den Registryschluessel ein: \n");
    gets(Schluesselname);
    printf("\n\n---------------------------------------------------\n");
    printf("Schluesselname:                  %s\n",Schluesselname);
    printf("Teilregistrierungsschluessel:    %s\n",Teilschluessel);
    strcpy (Gesamtschluessel, Teilschluessel);
    strcat (Gesamtschluessel, Schluesselname);
    printf("Gesamtregistrierungsschluessel:  %s\n",Gesamtschluessel);
    
    wprintf(L"\n\nWCHAR:  %s\n",KeyNameBuffer);
    
    printf("--------------------------------------------------- \n");
    
    wprintf(L"\n\nWCHAR:  %s\n",KeyNameBuffer);
    
    system("PAUSE");
    return 0;
    }
    


  • Okay, jeder hat mal angefangen, aber wozu schreibst du die Funktion, wenn du sie gar nicht aufrufst?
    Außerdem wird ein Zeiger zurückgegeben, dein KeyNameBuffer ist ein Array mit genau einem Element.
    Ferner solltest du Variablen so lokal wie möglich halten (also keine globalen Variablen benutzen).

    WCHAR* charToWide(const char* in)
    {
        WCHAR *KeyNameBuffer = malloc((strlen(in) + 1) * sizeof(WCHAR));
        if(KeyNameBuffer)
            MultiByteToWideChar(CP_ACP, 0, in, strlen(in) + 1, KeyNameBuffer, strlen(in) + 1); // insgesamt 3 strlen-Aufrufe, besser vorher speichern (siehe 1. Seite)
        return KeyNameBuffer;
    }
    
    int main()
    {
        const char* src = "irgendwas";
        wchar_t* dst = charToWide(src);
        if(dst)
        {
            // irgendwas  mit dst machen
            free(dst); // Freigabe nicht vergessen
        }
        return 0; // in C wohl nötig
    }
    


  • Nachtrag: Verwende auch besser kein gets, es gibt bessere Alternativen, siehe fgets.



  • bitte schaut euch nochmal den ZULETZT von mir geposteten Code an und bessert dann das aus, was falsch ist - den Funktionsaufruf bringe ich anscheinend nicht hin - irgendwas mach ich trotz vielem Lesen und Recherchieren falsch....

    Es wäre für mich viel einfacher, wenn bei einem Vorschlag von eurer Seite einfach mein gesamter Code mit den Änderungen von dir/euch gepostet wird - vielleicht kapier ichs dann - i hope so 😉

    PS: der Code muß auf jeden Fall C und nicht C++ sein....thx



  • Wir helfen gerne.
    Wir machen aber nicht deine Arbeit.

    #include <stdio.h>
    #include <windows.h>
    #include <stdlib.h>
    #include "reghide.h"
    
    WCHAR* charToWide(const char* Gesamtschluessel)
    {
    WCHAR *KeyNameBuffer = malloc((strlen(Gesamtschluessel) + 1) * sizeof(WCHAR)); // Dieses KeyNameBuffer hat mit dem KeyNameBuffer ein paar Zeilen tiefer nichst zu tun (außer Namensgleichheit).
    MultiByteToWideChar(CP_ACP, 0, Gesamtschluessel, strlen(Gesamtschluessel) + 1, KeyNameBuffer, strlen(Gesamtschluessel) + 1);
    return KeyNameBuffer;
    }
    
    WCHAR KeyNameBuffer[] = L"";  // Hier ist Platz für 0 Zeichen
    // Ausserdem kannst du einem Array keine Adresse zuweisen. 
    // Nimm einen Pointer, wie in deiner Funktion oben.
    
    char Teilschluessel[] = { "\\Registry\\Machine\\SOFTWARE\\Wow6432Node\\Classes\\CLSID\\" };
    char Gesamtschluessel[] = { "" }; // Hier ist Platz für 0 Zeichen
    
    int main ()
    {
    char Schluesselname[40];
    
    printf("Bitte geben Sie den Registryschluessel ein: \n");
    gets(Schluesselname); // besser fgets(Schluesselname,39,stdin) nehmen. 
    printf("\n\n---------------------------------------------------\n");
    printf("Schluesselname:                  %s\n",Schluesselname);
    printf("Teilregistrierungsschluessel:    %s\n",Teilschluessel);
    strcpy (Gesamtschluessel, Teilschluessel); // Wie gesagt ist in Gesamtschluessel Platz für 0 Zeichen 
    strcat (Gesamtschluessel, Schluesselname);  // DA passt nichts mehr rein.
    printf("Gesamtregistrierungsschluessel:  %s\n",Gesamtschluessel);
    
    wprintf(L"\n\nWCHAR:  %s\n",KeyNameBuffer);
    
    // Hier fehlt irgendwo der Aufruf von deiner Funktion charToWide()
    // KeyNameBuffer = charToWide(Gesamtschluessel); // oder so
    // geht aber nur, wenn KeyNameBuffer  ein Pointer ist.
    
    printf("--------------------------------------------------- \n");
    
    wprintf(L"\n\nWCHAR:  %s\n",KeyNameBuffer);
    
    system("PAUSE");
    return 0;
    }
    

    Ob das ganze MultibyteWidechar so in Ordnung ist, kann ich dir nicht sagen.
    Link: fgets



  • Hast du ein gutes Buch, um C zu lernen? Du solltest dir noch einmal das Kapitel über Zeiger und Arrays anschauen, wann brauchst du einen Zeiger, wann ein Array?
    Um Zeichenketten hintereinander zu hängen, bietet sich eine kleine Hilfsfunktion an:

    char* Concatenate(const char* fst, const char* sec)
    {
        size_t fstlen = strlen(fst);
        size_t seclen = strlen(sec);
        char* ret = malloc(fstlen+seclen+1);
        if(ret)
        {
            strcpy(ret, fst);
            strcpy(ret+fstlen, sec);
        }
        return ret;
    }
    wchar_t* charToWide(const char* src) // von der ersten Seite dieses Threads
    {
        size_t len = strlen(src);
        wchar_t* dst = malloc((len+1)*sizeof(wchar_t));
        if(dst)
        {
            if(!MultiByteToWideChar(CP_ACP, 0, src, len, dst, len))
            {
                free(dst);
                dst = 0;
            }
        }
        return dst;
    }
    

    Und die main (unvollständig):

    int main ()
    {
        WCHAR* KeyNameBuffer;
        char Teilschluessel[] = { "\\Registry\\Machine\\SOFTWARE\\Wow6432Node\\Classes\\CLSID\\" };
        char* Gesamtschluessel;
    
        char Schluesselname[40];
    
        printf("Bitte geben Sie den Registryschluessel ein: \n");
        fgets(Schluesselname, sizeof(Schluesselname), stdin);
    
        // ?
    }
    

    Den letzten Teil hätte ich dir jetzt auch noch hinschreiben können, tu dir aber selbst einen Gefallen und probiere es selbst zu lösen.


Anmelden zum Antworten