Seite 1 von 1
Brauche Hilfe bei String-Verarbeitung
Verfasst: 17. Juli 2009 15:57
von KartoffelKiffer
Hallo,
ich habe eine Funktion StrFromHex(QString *hex), welche den übergebenen &String (in hex konvertiert) in seine Urform umformt.
Die Zeichenkette sieht in etwa wiefolgt aus
Diese Funktion soll nun alle zwei Zeichen einlesen und diese wieder in dezimal umwandeln.
Sobald ich allerdings ein .mid(i, 2) auf die Zeichenkette mache (wobei i immer +2 ist), gibt mir qDebug folgendes aus
Die Zeichenkette umfasst knapp 10.000 Zeichen, ich weiß nicht ob mid, left und right (ich habe alle drei versucht) damit ihre Probleme haben. Ich kann es mir aber fast nicht vorstellen.
Langsam verweifel ich hier noch an einer solchen Banalität!
Eine ähnliche Funktion StrToHex sieht wiefolgt aus:
Code: Alles auswählen
void CKlasse_lib::StrToHex(QString *str)
{
qDebug(*str);
QString hex = "";
QChar c;
for (unsigned int i = 0; i < strlen(*str); ++i)
{
c = (*str).mid(i, 1).constref(0);
hex += QString("%1").arg((int)c, 0, 16);
}
*str = hex;
}
Und dort funktioniert alles tadellos. Keinerlei Probleme mit (*str).mid oder ähnliches.
Nicht nur qDebug gibt mit diese kryptischen Zeichen aus; auch wenn ich den Inhalt des Strings (mal angenommen ich habe (*hex).left(20) ausgelesen) in eine Datei schreibe, sieht er aus, wie die Debug-Mitteilung.
Irgendwie klappt da garnichts heute. Habe ich einen Denkfehler eingebaut oder sehe ich den Wald vor lauter Bäumen nicht mehr?!
Ich hoffe es kann mir geholfen werden.
// Edit: Sorry, ich habe vergessen meine Entwicklungsumgebung zu nennen: Qt 3.11 (!!!), MS VC++ 6.0
LG KK
Verfasst: 17. Juli 2009 16:20
von KartoffelKiffer
Hallo,
eine weiter Erkenntnis:
Code: Alles auswählen
qDebug(*hex);
qDebug("----");
QString str = (*hex).left(20);
qDebug(str);
Gibt folgendes aus:
Code: Alles auswählen
a426c61626c7562626c616161612e2e2e2e(...) ----
ö¨±K#Zu<?ø¸B£ÍGSa
Wobei das (...) in beiden Fällen (im vorherigen Beitrag auch) für die weiteren 9900 Zeichen steht.
Gut, Qt schreibt selber, dass der Puffer im qDebug "bloß" 8196 Zeichen fasst. Darüber komme ich hinaus. Aber auch ein Versuch komplett ohne qDebug (Debug quasi in Datei) kommt dieser Kauderwelsch zustande.
Ich weiß nicht mehr weiter....
LG KK
Verfasst: 17. Juli 2009 17:14
von Christian81
Wie soll das funktionieren:
Ich glaube QString::length() ist da wesenlich besser.
Das gleiche gilt für qDebug(*hex) - ich wüsste nicht wie das kompilieren soll und was da rauskommen sollte...
Und Code von deiner Funktion wäre auch nicht schlecht...
Verfasst: 21. Juli 2009 12:33
von KartoffelKiffer
Hallo Christian,
ich kann das Quell allen Übels genauer spezifizieren.
Code: Alles auswählen
qDebug(*text);
qDebug("---");
text->append(" ");
qDebug(*text);
qDebug("---");
Wobei *text die Dereferenzierung eines Zeigers auf einen übergebenen QString ist.
Der QString beinhaltet eine Zeichenkette von nun knapp 20.000 Zeichen. Ob dies unbedingt ratsam ist, weiß ich nicht. Bisher war es mein erster Versuch.
Die erste qDebug-Meldung gibt den String korrekt aus. Sobald ich an das Ende mittels append ein leeres Zeichen hinzufügen, und mir den Stirng erneut ausgeben möchte, kommt nur Kauderwelsch heraus. VC6 zeigt mir zB nur ?????????? an.
Hat QString nunmehr Probleme mit größeren Zeichenketten? So könnte ich mir auch die Problematik im ersten Beitrag mit left, mid und right erklären.
PS: Auch ein text->setLength(text->length()+1) erzeugt bei mir eine Zeichenkette, die nur aus ????? besteht.
LG KK
Verfasst: 21. Juli 2009 12:52
von Christian81
Es gibt keine Funktion qDebug(const QString&) - wie sollte das also kompilieren?
Siehe
http://doc.trolltech.com/4.5/qtglobal.html
/edit: Und falls es doch gehen sollte (aufgrund Qt3Support begleitet mit einer Warnung) ist es falsch - siehe Doku. Wenn in Deinem String ein printf()-Steuerzeichen vorhanden ist crasht es ...
Verfasst: 21. Juli 2009 14:01
von RHBaum
zumal selber geschriebene funktionen/methoden mit QString * parametern irgendwie aua sind.
warum ned referenzen ? Bei QT bist doch sowieso auf c++ seite ?
oder gibts nen technisch-logischen unterschied bei dir bei
void CKlasse_lib::StrToHex(QString *str)
zwischen
str == NULL;
*str.isEmpty() == true ;
DU hasst da eigentlich gleich 2 "ich habe gar kein String" Identifikatoren ^^
Ciao ...
Verfasst: 21. Juli 2009 14:52
von KartoffelKiffer
Ich bekomme es in sämtlichen Varianten nicht hin.
Code: Alles auswählen
QString CKlasse_lib::SetLength(QString text)
{
int line_size = text.length();
if (!(line_size%8) == 0 || line_size == 0)
{
//text.append(" ");
//text.setLength(text.length()+1);
text = QString("%1 ").arg(text);
return SetLength(text);
}
else
{
return text;
}
}
Die Funktion soll einfach solange ein Leerzeichen an den String anhängen, bis die Länge durch 8 teilbar ist.
Vor dem Funktionsaufruf wird mir der String korrekt ausgegeben (nicht durch 8 teilbar), nach dem Aufruf werden mir lediglich ????????? ausgegeben.
Das wüste Durcheinander mit dem Inhalt der Funktionen tut mir leid aber die Problematik ist immer dieselbe: Sobald der String zu groß ist (in meinem Fall knapp 20.000 Zeichen), tritt dieses Problem auf. Schreibe ich in den String bloß "123456" anstelle der 20.000 Zeichen, so funktioniert alles tadellos.
Kann es sein, dass mein String noch irgendwelche Sonderzeichen enthält, die QString irgendwie beirren? Theoretisch sollten in der Zeichenkette bloß Zahlen von 0-9 und Buchstaben von A-F stehen (hex halt).
So simpel es klingt: Ich möchte einfach nur eine Funktion haben, die an eine n Zeichen große Zeichenkette n Leerzeichen anhängt, sodass die Zeichenkette durch 8 teilbar ist.
LG KK
Verfasst: 21. Juli 2009 14:56
von CaptnChaos
Jetzt fang mal von ganz vorne an, was gibst du in den String rein, was soll raus kommen (Gib mal einen eingabe string und erklär was damit gemacht werden soll)?
Wir groß sind die integer die in hex umgewandelt werden? warum nicht '0x' als vorsilbe für jede Hexzahl wie es üblich ist?
Wenn du das nicht willst würde ich mit rightJustified arbeiten, damit ich wenigstens immer 2 zeichen für eine Hexzahl habe (01, 02 ... 0f, 10), dann löst sich das problem mit dem durch 8 teilbar von selbst.
Verfasst: 21. Juli 2009 15:11
von KartoffelKiffer
Gut, ich versuche es mal mittels Pseudocode zu erklären
Code: Alles auswählen
QString content = "";
QString content_hex = "";
content = QTextStream(datei).read();
content_hex.setLength(content*2); <-- jedes Zeichen im Ursprung wird in zwei Zeichen umgewandelt ( zB aus einem A wird 42 )
String2Hex(ursprung content, ziel content_hex); <-- jedes Zeichen wird einzeln umgewandelt und in content_hex geschrieben
content_hex = SetLength(text); <-- Funktionscode siehe ein Beitrag weiter oben
Vor dem Aufruf der SetLength(text)-Funktion steht in dem String eine Zeichenkette aus knapp 20.000 Zeichen. Diese habe ich zu Testzwecken in eine Datei geschrieben; sieht valide aus ( im Prinzip ist dies eine Aneinanderkettung von hex-zeichen, also 41525343483B2D29 etc ). Nach dem Aufruf beinhaltet mein String bloß noch ?????, welche mir auch in die Datei geschrieben werden.
Kann es sein, dass ich in der Denkweise bei dem
einen Fehler habe, sodass am Ende vielleicht noch Zeichen stehen, die nicht korrekt interpretiert werden?
Ich hoffe das Problem ist nun etwas klarer.
LG KK
Verfasst: 21. Juli 2009 15:23
von CaptnChaos
2 Funktionen:
Code: Alles auswählen
QString stringToHex(QString &string)
{
QString hex;
for(int i = 0; i < string.size(); i++)
hex += QString::number(string.at(i).unicode(), 16).rightJustified(2, '0');
return hex;
}
QString hexToString(QString &hex)
{
QString string;
bool ok;
for(int i = 0; i < hex.size(); i+=2)
string += (char)hex.mid(i, 2).toInt(&ok, 16);
return string;
}
Gebrauch:
Code: Alles auswählen
QString str("257254t25zj74h56i369");
QString hex = stringToHex(str);
qDebug(hex.toUtf8());
QString string = hexToString(hex);
qDebug(string.toUtf8());
Verfasst: 21. Juli 2009 18:16
von KartoffelKiffer
Hallo KernelPanic,
danke für Deine Mühe!
Bei meinem String handelte es sich um einen null-terminierten, sodass QCString für mich die richtige Wahl war! (bitte nicht vergessen, dass ich noch unter Qt3.11 arbeite(n muss)) Daher auch die "Abstürze" bei der Verwendung von QString.
Eine letzte Hürde (so hoffe ich) liegt noch vor mir.
Und zwar habe ich die Zeichenkette vollständig und problemlos umgewandelt bekommen, jedoch das in-die-Datei-schreiben bereitet mir noch ein Problem. Die "rohe" Zeichenkette besteht aus 19.071 Zeichen. Sobald ich folgenden Code verwende, reduziert sich die Länge auf 16.712.
Code: Alles auswählen
destination_stream << content_hex.ascii(); <-- content_hex ist vom Typ QString; length() gibt erfolgreich 19.071 Zeichen zurück
Die Konvertierungen mittels ascii(), latin1() und utf8() strippen automatisch ein paar Sonderzeichen aus meiner Zeichenkette, die ich allerdings zwingend benötige.
Entsprechend suche ich noch eine Funktion, die mir ein char* zurückliefert, um die "rohen" Daten in den Stream (die Datei) zu schreiben, sodass die Datei auch anschließend eine Größe von 19.071 byte hat.
LG KK
Verfasst: 21. Juli 2009 18:45
von phlox81
KartoffelKiffer hat geschrieben:Hallo KernelPanic,
Bei meinem String handelte es sich um einen null-terminierten, sodass QCString für mich die richtige Wahl war! (bitte nicht vergessen, dass ich noch unter Qt3.11 arbeite(n muss)) Daher auch die "Abstürze" bei der Verwendung von QString.
Eine letzte Hürde (so hoffe ich) liegt noch vor mir.
Und zwar habe ich die Zeichenkette vollständig und problemlos umgewandelt bekommen, jedoch das in-die-Datei-schreiben bereitet mir noch ein Problem. Die "rohe" Zeichenkette besteht aus 19.071 Zeichen. Sobald ich folgenden Code verwende, reduziert sich die Länge auf 16.712.
Code: Alles auswählen
destination_stream << content_hex.ascii(); <-- content_hex ist vom Typ QString; length() gibt erfolgreich 19.071 Zeichen zurück
Die Konvertierungen mittels ascii(), latin1() und utf8() strippen automatisch ein paar Sonderzeichen aus meiner Zeichenkette, die ich allerdings zwingend benötige.
Entsprechend suche ich noch eine Funktion, die mir ein char* zurückliefert, um die "rohen" Daten in den Stream (die Datei) zu schreiben, sodass die Datei auch anschließend eine Größe von 19.071 byte hat.
Versuch mal data(), ansonsten gibts auch noch das Manual:
http://doc.trolltech.com/3.1/qstring.html 
Verfasst: 21. Juli 2009 19:03
von KartoffelKiffer
Hallo,
tur mir leid, das hatte ich vergessen zu schreiben: data() habe ich auch versucht, ohne Erfolg.
Gibt es noch irgendwelche Alternativen, die so aus dem manual nicht gleich ersichtlich sind? Ich weiß nicht mehr weiter, dabei stehe ich so kurz davor.
Verfasst: 22. Juli 2009 06:29
von Christian81
Verfasst: 22. Juli 2009 15:16
von RHBaum
Also so hundertprozentig schlau werd ich aus der aufgabenstellung auch noch ned ....
Du liesst die zeichen ein ...
Was steht da in der Datei genau drinne ... ist das eine TextDatei ? Haben Zeilenumbrauch eine Bedeutung fuer deine Logik ?
Zeichen werden gewandelt ...
Das 'A' (Ascii code 42) soll zu "42" convertiert werden ... soweit ok.
Was wird mit nichtsichtbaren zeichen ? Gibt es die ueberhaupt ?
Bleibt der Zeilenumbruch ? oder soll der auch convertiert werden ?
Wie schaut es mit tabulatoren aus ?
Whitespaces werden auch convertiert ?
Prinzipiell wuerd ich auch ned 19kbyte am stueck einlesen, sondern nen puffer mit vernuenftiger groesse waehlen ....
QString egal welche qt version wuerd ich gar ned nehmen .... QString ist intern nen Widestring ... das blaeht deinen speicherverbrauch auf und beschert dir mehrfache convertierungen.
warum ueberhaupt die qt zu bemuehen ? grad die stl inkl. der iostream lib sind extra fuer solche anwendungen geschaffen wurden ....
Mit der STL muss man sich eh mal auseinandersetzen wenn man ernsthaft programmieren will ....
std::string und ifstrem/ofstream sind zwar bissi trickiger zu verwenden, haben aber mehr transparenz und sind unabhaengiger als wie das qt zeugs .....
Ciao ....