Umwandlung QString in ascii bzw. char *



  • Unten fehlt natürlich noch der eigentliche cast:

    QString *q=new QString("Teststring");
    char *str=strdup((const char *)(*q));
    


  • oder so:

    QString q; 
     	q = "Teststring"; 
    	const char *str; 
     	str = q.ascii();
    

    das müsste funzen

    //Edit: Codetag geschlossen.(evilissimo)



  • dann liegt mein Problem woanders:

    also ich gebe in ein QLineEdit led einen Text ein und lese ihn mittels
    led->text() in einen QString aus. (und wandele ihn um)

    Alles ok.
    ABER: wenn in diesem eingegebenen Text vorkommt
    %d5
    dann wird stattdessen irgendeine Zahl (vermutl. ein Pointer)
    zurückgegeben.
    Beispiel:
    aus
    abc %d5
    wird
    abc -1806548

    Wobei sich diese grosse Zahl ändert, je nach Eingabe.

    Deshalb hatte ich erst vermutet, dass es an meiner Umwandlung von Qstring in
    ascii liegt. Dann muss die Ursache eine andere sein.
    Warum also wird in einem QLineEdit spezieller Text, der mit einem % beginnt
    irgendwie umgewandelt ?



  • malabarista schrieb:

    dann liegt mein Problem woanders:

    also ich gebe in ein QLineEdit led einen Text ein und lese ihn mittels
    led->text() in einen QString aus. (und wandele ihn um)

    Alles ok.
    ABER: wenn in diesem eingegebenen Text vorkommt
    %d5
    dann wird stattdessen irgendeine Zahl (vermutl. ein Pointer)
    zurückgegeben.
    Beispiel:
    aus
    abc %d5
    wird
    abc -1806548

    Wobei sich diese grosse Zahl ändert, je nach Eingabe.

    Deshalb hatte ich erst vermutet, dass es an meiner Umwandlung von Qstring in
    ascii liegt. Dann muss die Ursache eine andere sein.
    Warum also wird in einem QLineEdit spezieller Text, der mit einem % beginnt
    irgendwie umgewandelt ?

    Könntest du uns ein kleines Beispielprogramm zeigen, dass den Fehler zeigt?



  • Ich habe mal die wichtigsten Programmteile zusammenkopiert,
    so in etwa sieht es aus.
    Der springende Punkt ist mit ****** markiert.

    Teinzelfeld::Teinzelfeld(char *titel, char*text, int x, int y,QWidget *parent, const char *name, bool modal, WFlags f )
            : QDialog( parent, name, modal, f )
    {
    int b,h;
    
    b=300;
    h=60;
    setGeometry(x,y,b,h);
    
    ein=new QLineEdit(this);
    ein->setGeometry(10,5,150,20);
    ein->setMaxLength(laenge);
    ein->show();
    setCaption(titel);
    connect(ein, SIGNAL(returnPressed()), this, SLOT(fertig()));
    }
    
    void Teinzelfeld::fertig(void)
    {
    done(1);
    }
    
    ////////////////////////////////////////
    
    void einzel_eingabe(char *ausgabe)
    {
    int ruck;
    char zaus[80];
    QString zq;
    Teinzelfeld *ef;
    
    strcpy(zaus,"");
    strcpy(ausgabe,"");
    ef=new Teinzelfeld(titel,"",10,20,30,pan_window);
    ruck=ef->exec();
    if (ruck>0)
       {
       zq=ef->ein->text();  //******** hier taucht der Unsinn in ZQ auf
       strcpy(zaus,zq);
       }
    delete ef;
    strcpy(ausgabe,zaus);
    }
    

    Im Prinzip wird nur ein QLineEdit auf einem Dialogfenster plaziert
    und bei <ENTER> die Eingabe eingelesen.
    Wie gesagt, solange man keine % eingibt, klappt es gut,
    aber mit
    %d5
    geht es fürchterlich daneben.

    //Edit: Bitte Codetags verwenden (evilissimo) ⚠ sfds ⚠



  • Das sieht ja furchtbar aus. Entschuldige diese Aussage, aber das war mein erster Gedanke.

    Du startest die Qt Event Loop nur für die Dialogbox? Das erscheint mir auf Dauer nicht sonderlich effizient. Was machst du eigentlich mit diesem Code? Und wozu brauchst du unsichere C Strings?

    Ich habe mal deinen Code in etwas lauffähiges gepackt und es funktioniert einwandfrei hier. Vielleicht solltest du uns auch etwas lauffähiges zeigen, damit wir deinen Fehler sehen. Deine einzel_ausgabe Funktion sollte aber -- falls es unbedingt in diesem Stil sein muss -- zumindest so aussehen:

    char *  einzel_eingabe(char *ausgabe, std::size_t length)
    {
       Teinzelfeld ef("titel", "", 10, 20);
       int ruck = ef.exec();
       if (not ruck) return 0;
       strncpy(ausgabe, ef.ein->text().ascii(), length);
       ausgabe[length-1] = 0;
       return ausgabe;
    }
    


  • char *  einzel_eingabe(char *ausgabe, std::size_t length)
    {
       Teinzelfeld ef("titel", "", 10, 20);
       int ruck = ef.exec();
       if (not ruck) return 0;
       strncpy(ausgabe, ef.ein->text().ascii(), length);
       ausgabe[length-1] = 0;
       return ausgabe;
    }
    

    ⚠ sfds ⚠

    sorry,
    bei mir bleibt immer noch der gleiche Effekt:
    wenn ich (ohne Anführungsstriche) eingebe
    "abc %d5 h"
    steht anschliessend (auch ohne Anführungsstriche) in der Variablen ausgabe
    "abc 15 h"

    und aus
    "abc %5d g"
    wird
    "abc 1 g"

    Und das ist bei dir nicht der Fall ??

    Zu deinen Fragen bzw. Anmerkungen:
    Ich verwende diese "einzel_eingabe" immer in den Fällen,
    wo lediglich ein einzelnes Eingabefeld notwendig ist (z.B. für einen Dateinamen).

    Über Programmierstil kann man streiten,
    - ich bin zur Zeit dabei meinen C-Code von Windows unter Linux bzw. einer Linux-GUI lauffähig
    zu machen.
    Und Übersichtlichkeit ist auch eine Gewöhnungssache:
    ich z.B. hasse es, wenn Variablen-Definitionen mitten im Code stehen.
    Die gehören in den Kopf einer Funktion, - leider geht dies bei C++ nicht immer.

    Ferner stehe ich auf dem Standpunkt, dass Programmcode wiederverwendet werden sollte.
    Dann wird er zwar etwas umfangreicher (weil er manche Sonderfälle abdecken muss),
    aber der Gewinn liegt darin, dass der verwendete Code stets (relativ) fehlerfrei ist und
    im Fehlerfalle nur eine Code-Änderung notwendig ist, um den Fehler in allen
    meinen Projekten zu beheben. Es müssen lediglich alle Projekte neu kompiliert werden.

    Aber wie gesagt, ich möchte keine Diskussion über Programmierstil lostreten,
    das haben schon viele andere Leute vor uns getan und sind nicht zu einem
    Ergebnis gekommen (ich denke hier z.B. an die unselige Diskussion, ob man ein
    "goto-Statement" verwenden sollte oder nicht).



  • Bei mir wird, egal was ich eingebe, das auch ausgedruckt. Könntest du nicht das Problem so isolieren, dass man es direkt testen kann? Vielleicht tritt dann der Fehler bei mir auch auf.

    Hier ist mal das Programm, was ich um deinen Code herum gestrickt habe:

    main.cpp:

    #include <iostream>
    #include <qapplication.h>
    #include "dialog.H"
    
    char *  einzel_eingabe(char *ausgabe, std::size_t length)
    {
       Teinzelfeld ef("titel", "", 10, 20);
       int ruck = ef.exec();
       if (not ruck) return 0;
       strncpy(ausgabe, ef.ein->text().ascii(), length);
       ausgabe[length-1] = 0;
       return ausgabe;
    }
    
    int main(int argc, char ** argv) {
    
        QApplication a( argc, argv );
    
        char buffer[1024];
    
        if (einzel_eingabe(buffer, 1024))
          std::cout << buffer << std::endl;
    }
    

    dialog.H

    #include <qdialog.h>
    #include <qlineedit.h>
    #include <qdialog.h>
    
    class Teinzelfeld : public QDialog {
       Q_OBJECT
    public:
       Teinzelfeld(char *, char*, int, int, QWidget * parent = 0, const char * name = 0, bool modal = 0, WFlags f = 0);
    public slots:
       void fertig();
    
       QLineEdit * ein;
    };
    

    dialog.cpp:

    #include "dialog.H"
    
    Teinzelfeld::Teinzelfeld(char *titel, char*text, int x, int y,QWidget *parent, const char *name, bool modal, WFlags f )
    : QDialog( parent, name, modal, f )
    {
    int b,h;
    
    b=300;
    h=60;
    setGeometry(x,y,b,h);
    
    ein=new QLineEdit(this);
    ein->setGeometry(10,5,150,20);
    ein->setMaxLength(30);
    ein->show();
    setCaption(titel);
    connect(ein, SIGNAL(returnPressed()), this, SLOT(fertig()));
    }
    
    void Teinzelfeld::fertig()
    {
    done(1);
    }
    

    Was den Stil angeht:

    1. Ich glaube, dass meine Version nicht weniger allgemein ist als deine.
    2. Variablen sollte man in C++ aus Performanzgründen so spät wie möglich anlegen.
    3. Du verwendest das unsichere strcpy.
    4. Du verwendest drei strcpy Aufrufe. Mir reicht ein strncpy
    5. Ich lege kein Objekt auf dem Heap an und muss es damit auch nicht löschen.

    Ich will nicht sagen, dass ich es im tatsächlichen Code so machen würde, wie ich es hier gezeigt habe, aber in dieser Richtung.



  • Jetzt bin ich von den Socken:

    ich habe auf meiner Applikation zusätzlich ein Label angelegt und den Inhalt dorthin
    ausgegeben:
    Ergebnis: alles steht korrekt im Label.

    Und die tatsächliche Ursache habe ich jetzt auch entdeckt:
    zu Testzwecken habe ich immer den String in eine Datei geschrieben und mir diese Datei
    später angesehen.
    Und zwar habe ich mit "fprintf" geschrieben und der interpretiert die Strings, wenn ein % vorkommt.
    Das habe ich jetzt mittels "man" nachgelesen.

    Also: eine ganz zerknirschte Entschuldigung und dankeschön für deine Bemühungen.



  • malabarista schrieb:

    Jetzt bin ich von den Socken:

    ich habe auf meiner Applikation zusätzlich ein Label angelegt und den Inhalt dorthin
    ausgegeben:
    Ergebnis: alles steht korrekt im Label.

    Und die tatsächliche Ursache habe ich jetzt auch entdeckt:
    zu Testzwecken habe ich immer den String in eine Datei geschrieben und mir diese Datei
    später angesehen.
    Und zwar habe ich mit "fprintf" geschrieben und der interpretiert die Strings, wenn ein % vorkommt.
    Das habe ich jetzt mittels "man" nachgelesen.

    Also: eine ganz zerknirschte Entschuldigung und dankeschön für deine Bemühungen.

    Aus Schaden wird man klug. Ist doch ein guter Grund, nicht mehr die alten C Funktionen zu verwenden.


Anmelden zum Antworten