string to char /wieder aufgegriffen



  • Hallo Profis,

    ich verwende Microsoft Visual C++ Express 2005 und möchte in einer Windows-Forms- Anwendung aus einem String gern ein char[] machen.
    Dazu habe ich bisher aus dem Beitrag "char to string & string to char" entnommen, dass mit der Funktion "c_str()" ein "String" in ein "const char" umgewandelt werden könnte. In der Hilfe ist sogar ein Beispiel enthalten. Leider gibt folgender TestCode:

    void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        String ^str1 = gcnew String(test);
      //const char *c_str1 = str1.c_str ( ); //Fehler1
      //const char *c_str1 = str1->c_str ( ); //Fehler2
    }
    

    folgende Fehler:
    Fehler1: error C2228: Links von ".c_str" muss sich eine Klasse/Struktur/Union befinden
    Fehler2: error C2039: 'c_str': Ist kein Element von 'System::String'

    Scheinbar kennt "String" die Methode "c_str()" nicht. Hier ist mal noch ein kleines Programm, in welchem ich versucht habe zu illustrieren, worum es mir geht.

    void button1_Click(System::Object^  sender, System::EventArgs^  e) {
    
    //String ^test2 = gcnew String("string");
    //char test3[] = test2;   // das hätte ich gerne - geht aber leider nicht
    
    }
    

    Ich würde mich sehr darüber freuen, falls jemand weis, wie man dieses Programm funktionsfähig bekommt.

    MfG.



  • Aus der FAQ:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-158664.html
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-158666.html

    Warum benötigst Du das überhaupt?
    Oft ist es ein Fehler managed und native zu mischen...

    Simon



  • Hallo Simon,

    vielen Dank für den Link auf den Forenbeitrag zur Umwandlung von String in const char *.
    Ich habe die struct "StringConvA" in eine Windows- Forms -Anwendung eingebaut und gehofft mit strcpy das const char * in ein char[] umzuwandeln.

    //Testprogramm
    void Form1::button2_Click(System::Object^  sender, System::EventArgs^  e) {
    
      String ^str1 = gcnew String("LILA");
      const char *zeigeraufa = (LPCSTR) StringConvA(str1); 
      char dest[4]; 
      strcpy(dest, zeigeraufa);
    
     //Funktion(dest);
     //Rückumwandlung - nur zum Test!
      String ^test = gcnew String(dest);
      textBox1->Text = test;  
    
    }
    

    Leider kamen da nur drei merkwürdige Symbole an: •.•
    Tja was kann man da noch machen ?
    So sieht übrigens die Funktion aus, an die ich gerne ein char &str[] übergeben hätte:

    int	Funktion(void *CHARS)
    {
    //
    //  andereFunktion(CHARS);
    //        
    	return 1;
    }
    

    Vielleicht habe ich bei der Umsetzung auch einen Fehler gemacht.

    MfG.



  • 7x7-7 schrieb:

    //Testprogramm
    void Form1::button2_Click(System::Object^  sender, System::EventArgs^  e) {
    	
      String ^str1 = gcnew String("LILA");
      const char *zeigeraufa = (LPCSTR) StringConvA(str1); 
      char dest[4]; 
      strcpy(dest, zeigeraufa);
     
     //Funktion(dest);
     //Rückumwandlung - nur zum Test!
      String ^test = gcnew String(dest);
      textBox1->Text = test;  
    
    }
    

    Nur Vermutungen (wenn falsch, bitte sagen):

    Mein gefühl sagt mir, dass dest 5 Elemente haben soll ( LILA + Nullchar ).
    Ist aber nicht char[] == *char? Dann kannst du über const_cast (o.s.ä.) "StringConvA(str1) direkt nach char[] umwanden.
    Wenn du auf x64 bist, wüsste ich übrigens noch einen potentienllen Fehler.



  • Hallo Rhombicosidodecahedron,

    ich habe mal mit const_cast experimentiert und kein Erfolg gehabt. Ich habe allerdings unterdessen einen wahrscheinlich uneleganten workaround gefunden, der möglicherweise verbesserungsfähig ist.

    //Testprogramm
    void Form1::button2_Click(System::Object^  sender, System::EventArgs^  e) {
    
       String^ str1 = gcnew String("LILA");
    
       char a;
       char buffer[]= "****";
       int count, length;
       count = 0;
       length = str1->Length;
       while(count < length){
       a = Convert::ToChar(str1->Substring(count,1));
       buffer[count] = a;
       count++;
       }
    
       String^dest = gcnew String(buffer);
       MessageBox::Show(dest);
    
    }
    

    Schön wäre, wenn jemand wüsste, wie ich char[] schon auf die Länge des Strings festlegen könnte. Wenn ich length einsetze, dann gibt der Compiler die Fehlermeldung:
    C2057: Konstanter Ausdruck erwartet ;
    C2466: Zuordnung einer Arrays der konstanter Größe 0 nicht möglich;

    MfG.



  • Hier mal ein Bsp. (ohne Widechar > Multibyte Konvertierung und ohne Null Terminierung):

    using namespace System;
    
    void f(void* data)
    {
        data;
    }
    
    #include <vector>
    
    typedef std::vector<wchar_t> WCharBuffer;
    
    WCharBuffer convert(String^ str)
    {
        WCharBuffer buf;
    
        for each (Char ch in str)
        {
            buf.push_back(ch);
        }
    
        return buf;
    }
    
    WCharBuffer::pointer c_array(WCharBuffer& buf)
    {
        return buf.empty() ? 0 : &buf.front();
    }
    
    int main(array<System::String ^> ^args)
    {
        String^ str = L"test";
        WCharBuffer buf = convert(str);
        f(c_array(buf));
    }
    


  • Hallo Simon,

    Dein Code funktioniert prima.
    Jedoch scheint bei meinem Anwendungsfall die Nullterminierung notwendig zu sein. Die Funktion f stellt nämlich das Interface zu einer Hardwarekomponente dar, in deren Eingangspuffer ich neben der Zeichenkette im String str auch zusätzliche Zeichen nachweisen konnte. Woher diese Zeichen genau kommen, vermag ich gegenwärtig nicht zu sagen. Jedoch habe ich auch gefunden, dass bei einer manuell eingefügten Nullterminierung diese zusätzlichen Zeichen nicht in Erscheinung treten.

    String^ str = L"test\0";
    

    Dein Beispiel hat mir beim Verständnis der verschiedenen String- ähnlichen Datentypen sehr weitergeholfen -

    Vielen Dank !
    MfG.



  • Die Null Terminierung kannst Du einfach noch einbauen:

    WCharBuffer convert(String^ str) 
    { 
        WCharBuffer buf; 
    
        for each (Char ch in str) 
        { 
            buf.push_back(ch); 
        } 
    
        // Null- Terminierung einfügen
        if (str->Length != 0)
        {
            buf.push_back(0);
        }
    
        return buf; 
    }
    


  • Hallo Simon,

    ich habe Deine zweite Variante mit Nullterminierung getestet und gefunden, dass diese ausgezeichnet funktioniert. Ferner hatte ich auch gefunden, dass durch manuelles Anhängen von „\0“ an einen zu konvertierenden String nicht unbedingt eine Nullterminierung stattfindet.
    Deine Variante ist somit der sicherste Weg.

    Vielen Dank nochmal.
    MfG.


Anmelden zum Antworten