Seite 1 von 1

Bilden eines QString aus einem char-Array mit max. Länge

Verfasst: 8. Mai 2009 15:13
von Tilman Räger
Hallo,

Ich habe das Problem, das ich aus einem Datensatz Character-Arrays in QString-Objekte überführen muß. Solange diese Arrays nicht bis zur Halskrause gefüllt sind, kein Problem.

Code: Alles auswählen

QString::fromLatin1(array);
wenn ich sicher sein kann, das der String immer voll gefüllt ist, ebenfalls kein Problem:

Code: Alles auswählen

QString::fromLatin1(array, sizeof(array));
Probleme tauchen auf, wenn der String mal mit \0 abgeschlossen ist, mal bis zum letzten Byte mit druckbaren Zeichen gefüllt ist.
Verwende ich die 1. Variante, wird mir an die voll gefüllten Strings hinten der Inhalt der nächsten Felder angehängt (solange nicht \0), verwende ich die 2. Variante, versucht mir Qt, auch die am Ende befindlichen, nichtdruckbaren Zeichen (\0 plus der restliche Inhalt bis zum Ende des Arrays) anzuzeigen. Beides nicht ganz erfreulich.
Ich kann zwar das ganze dahingehend umgehen, das ich entweder vorher mit memcpy in ein größeres, mit \0 vorbelegtes Array umkopiere, oder das mit QString::fromLatin1(array) erzeugte QString-Objekt hinterher mit truncate(int) oder left(int) abschneide, aber beides ist natürlich nicht allzu elegant und ich werde den Verdacht nicht los, das QString eine entsprechende Funktion schon mitbringt - oder liege ich hier falsch?

Wie würden außerdem truncate() bzw. left() bei UTF8 arbeiten, wenn die Anzahl der Character nicht mit der der Bytes übereinstimmt?

Gruß
Tilman (Räger)


[/code]

Verfasst: 8. Mai 2009 16:08
von Christian81
Warum nicht immer QString::fromLatin1(array, sizeof(array)); ?

Verfasst: 11. Mai 2009 17:06
von Tilman Räger
Rückfrage von Christian81:
Warum nicht immer QString::fromLatin1(array, sizeof(array)); ?
Weil QString dann über das abschließende \0 im array hinwegliest und mir den String bis zu der Größe sizeof(array) mit nicht-Druckbaren Zeichen auffüllt, was nicht so prickelnd aussieht.

Gruß
Tilman

Verfasst: 11. Mai 2009 17:15
von -=Freaky=-
koennte man nicht anstatt sizeof() strlen() benutzen?

mfg,
julian

Verfasst: 11. Mai 2009 17:22
von Christian81
Dann eben nach \0 suchen und den korrekten Wert übergeben.

Verfasst: 11. Mai 2009 17:33
von RHBaum
Warum nicht das array um 1 byte grosser machen, und damit sicherstellen, das das letzte zeichen immer null ist ...

dann kannst immer die variante mit dem lesen bis zum zeichenende verwenden .... also funktion verwenden die das impliziet macht (QString::fromLatin1(array) )!

Ciao ....

Verfasst: 12. Mai 2009 12:24
von Tilman Räger
Hallo,

danke erst mal für die diversen Antworten. Das waren im Prinzip die Wege, die wir bisher auch gegangen sind - mit Ausnahme des Vergrößerns des Arrays, das geht beim besten Willen nicht.

Was mich in erster Linie interessierte, war, ob es vielleicht eine Funktion gibt, die das ganze in einem Schritt macht, d.h. das man in EINEM Schritt das Array einlesen kann, unabhängig davon, ob es bis zum Rand gefüllt ist oder nicht. Der Grund ist einfach, das man bei der Entwicklung doch ständig wieder darüber stolpert, das der eine oder andere eben die besonders erforderliche Bearbeitung vergisst.

Gruß
Tilman (Räger)

Verfasst: 12. Mai 2009 12:52
von AuE
gibts die möglichkeit das als std::vector zu bekommen? dann könntest mit nen itr durchgehen!

Verfasst: 12. Mai 2009 15:12
von RHBaum
Was mich in erster Linie interessierte, war, ob es vielleicht eine Funktion gibt, die das ganze in einem Schritt macht
Definitiv NEIN !

weil, einen string zu lesen bis zum ende zeichen (0) und eine kopie von erstellen,

und

aus einem string so und soviel zeichen zu kopieren, ohne ruecksicht auf ein Stringende , sind 2 verschiedene Schuhe.

Der clou der ganzen geschichte, nen Stringende stoert dich eh kaum, weil selbst wenn mehr kopierst, die C-Interpretation des Strings bleibt gleich ...

Funktionen wie strncpy z.b. muessen nur sicherstellen:
- das der String mindestens bis zum Stringende , oder aber bis zum angegebenen ende (n) kopiert wird.
- nicht ueber n stellen im ziel drueber hinaus kopiert wird (access violation)

Ob die strncpy funktion im Detail nun genau bis zum Stringende kopiert, oder sturr n Zeichen kopiert ... oder grosser bis stringende aber kleiner gleich n und ein vielfaches von 4 .... das ist runtimespezifisch, und die C-Funktionalitaet hat das ned zu intressieren.

deine skrupel, nen String ned mehr als x zeichen reinzupumpen, in allen Ehren, aber man muss von situation zu situation entscheiden.

nen check ob und wo nen zeichenende zu finden ist, kann um welten inperformanter sein, als zig bytes mehr zu kopieren

Die entscheidung kann und wird dir der compiler ned abnehmen wollen.

Um welche groesse handelt es sich eigentlich ? kann so schlimm ned sein, wenn es aus nem statischen puffer kommt ....

gibts die möglichkeit das als std::vector zu bekommen? dann könntest mit nen itr durchgehen!
warum erst einen vector bekommen ???
Der Clou ist eigentlich, das Iteratoren sich verhalten wie Zeiger auf einArray ... deinArray iss also die Vorlage, das Vorbild, fuer das Iterator Verhalten ... und du kannst ohne Probleme stl - Like uber nen C-Array iterieren !!!

Code: Alles auswählen

for(char * myIter = &Array[0], myIter != &Array[anz]; ++myIter)
{
   char & ref = *myIter;


}
Ciao ....

Verfasst: 12. Mai 2009 15:15
von AuE
Ich sah den Wald vor lauter RHBaumen nicht :-D stimmt.... dann kannst du doch va diesen mechanismus mit nen Funktor wunderbar nach beliebigen zeichen durchsuchen!

Verfasst: 12. Mai 2009 15:19
von RHBaum
und noch toller, alle stl- Algos funktionieren auch mit zeiger auf arrays .. da die sich ja genau so verhalten wie Iteratoren, oder andersrum :lol: !?

Wobei das was er sucht das StringEndezeichen sein sollt ....
dafuer gibts wiederum ne spezialisierte funktion im Ansi C, die mit max. Performance implementiert sein sollte:
str(n)len !!!

Ciao ...

Verfasst: 13. Mai 2009 15:49
von Tilman Räger
Hallo,

die definitive Antwort habe ich befürchtet, aber sei's drum.

Intention war, eine standardisierte Funktion verwenden zu können, anstelle das jeder Entwicker im Team seine eigene Routine erstellt bzw. jedesmal, wenn das Problem auftritt es wieder ein wenig anders macht. Muß ich also evtl. meine eigene Routine erstellen.

Trotzdem mal Danke für alle antworten.

Gruß
Tilman (Räger)

PS: noch ne kurze Frage - wie setze ich so einen Beitrag auf gelöst?

Verfasst: 13. Mai 2009 16:05
von AuE
was macht denn boost damit ?

habs leider net getestet für nen array und auch net in der doku geschaut....

Code: Alles auswählen

template <class T> 
	std::string to_stringT( T &value )
	{ 
		//std::string svalue = "";	
		try{
			return boost::lexical_cast<std::string, T>(value);

		}catch(boost::bad_lexical_cast &e){
			std::cerr<<"string_support::exception: to_string(): bad_lexical_cast: '"<<e.what()<<"' value: "<<value<<std::endl;
		}
		return "";
	}

Verfasst: 13. Mai 2009 18:16
von Tilman Räger
was macht denn boost damit ?
Keine Ahnung, da wir kein boost verwenden, kann ich darüber nichts sagen.

Gruß
Tilman (Räger)