ASCII Wert aus einem AnsiString[n] lesen
-
Das weiss ich wohl.
Steht ja auch so (aehnlich) in meinem Listing:substr(i,1)
Trotzdem bekomme ich Datenmüll.
Das sieht übrigens auch nicht anders aus, wenn ich
for (i=1;i<=AllData.Length();i++){ SS = AllData[i]; z = (char)SS.c_str(); fprintf(stream, "%3u = %2Xh = %c\r\n", z,z,z); }
mache.
Mein erstes Beispiel war halt eines von tausend Versuchen.So müsste zum Beispiel als erste Zeichen ein String ankommen:
"Frankfurt"
Also wuerde ich gerne in meinem Logfile folgendes Format haben:
70 46 F
114 72 r
97 61 a
110 6E n
107 6B k
102 66 f
117 75 u
114 72 r
116 74 t(So in der Art)
Stattdessen erhalte ich aber:
4294967196 = FFFFFF9Ch = œ
116 = 74h = t
4294967196 = FFFFFF9Ch = œ
116 = 74h = t
4294967196 = FFFFFF9Ch = œ
116 = 74h = t
4294967196 = FFFFFF9Ch = œ
116 = 74h = t
4294967196 = FFFFFF9Ch = œ
116 = 74h = t
4294967196 = FFFFFF9Ch = œ
116 = 74h = t
4294967196 = FFFFFF9Ch = œ
116 = 74h = tusw.
Da stimmt halt gar nichts drin.
-
Hallo stoerti,
mit der Methode c_str() erhältst Du einen Pointer auf den internen Stringbuffer eines AnsiStrings. Damit hast Du Zugriff auf die einzelnen Zeichen des Strings.
AnsiString AllData = "Dieses ist ein String";
char z;
for (int i=0;i<=AllData.Length();i++){
z = AllData.c_str()[i];
}Aber Achtung: Dieser Zeiger hat nur Gültigkeit innerhalb deiner Anweisung. In diesem Fall der for-Schleife. Solltest Du einen persistenten Pointer benötigen, ist es besser den String in einen seperaten Buffer zu kopieren:
char* MyBuffer = new char[ AllData.Length() + 1 ];
strcpy( MyBuffer, AllData.c_str() );Und natürlich nicht vergessen, den Buffer nach Beendigung mit delete wieder freizugeben
Gruß
Gerhard
-
Gerhard schrieb:
mit der Methode c_str() erhältst Du einen Pointer auf den internen Stringbuffer eines AnsiStrings.
Zu früh aufgestanden?
Das ist zwar prinzipiell richtig, hat aber absolut nichts mit dem Problem zu tun.char z = AllData[i]; fprintf(stream, "%3u = %2Xh = %c\r\n", z,z,z);
Wie von Sunday schon gezeigt.
Dieser Zeiger hat nur Gültigkeit innerhalb deiner Anweisung.
Das ist schlichtweg falsch. c_str ist nur im Moment der Übergabe gültig, schon in der nächsten Zeile ist der Inhalt nicht mehr garantiert. Siehe auch die FAQ unter "AnsiString".
-
Hi,
falls es noch nicht klappt, versuch mal:
int dezVal; for (int i=1;i<=AllData.Length();i++){ dezVal = (int)AllData[i]; fprintf(stream, "%3u = %2Xh = %c\r\n", dezVal,dezVal,dezVal); }
CU
-
O.k,O.k,
wollte Dir eigentlich nur helfen den unnötigen Aufruf von Substirng
SS = AllData.SubString(i,1);
z = (const char*)SS.c_str();
zu elimieren und zeigen wie man korrekt auf ein char eines AnsiStrings zugreift. Wenn ich Dein Problem nicht richtig verstanden habe tut es mir leid.
Übrigens, Deine Meinung dass der Zeiger c_str() nach der Übergabe nicht mehr gültig ist, ist leider nicht korrekt ! Er behält innerhalb eines Schleifenkörpers und das ist eine for oder while Schleife absolut seine Gültigkeit.Gruß
Gerhard
-
Gerhard schrieb:
wollte Dir eigentlich nur helfen
Danke, aber ich bin doch gar nicht störti.
zeigen wie man korrekt auf ein char eines AnsiStrings zugreift
"Korrekt" ist str[n], nicht str.c_str()[n]. Auch wenn letzteres auch funktioniert.
dass der Zeiger c_str() nach der Übergabe nicht mehr gültig ist, ist leider nicht korrekt ! Er behält innerhalb eines Schleifenkörpers und das ist eine for oder while Schleife absolut seine Gültigkeit.
Tatsächlich? Probier doch mal das hier aus:
String str1 = "abc", str2 = "123"; char *ptr1, *ptr2; for (int i = 0; i < 5; i++) { ptr1 = str1.c_str(); ptr2 = str2.c_str(); str1 = "def"; str2 = "456"; Memo1->Lines->Add("String1: " + String(ptr1)); Memo1->Lines->Add("String2: " + String(ptr2)); Memo1->Lines->Add("---"); }
Schon komisch, oder?
-
Rincewind, vielen Dank!
So hats geklappt.
-
Nein,
komisch ist das nicht, weil falsch !!
Was Du da als Beispiel anführst, hat nichst aber auch gar nichts mit
der Schleife
for (int i=0;i<=AllData.Length();i++){
z = AllData.c_str()[i]; }
zu tun. Die, was nicht komisch ist, immer wieder funktionieren wird !
Wenn Du also über die Gültigkeit von Pointern auf das char-Feld eines Ansistrings diskutieren möchtest, dann bleibe bitte Korrekt. Ich weiß sehr wohl, wann diese verlorengeht. Deshalb auch mein Hinweis:"Solltest Du einen persistenten Pointer benötigen, ist es besser den String in einen seperaten Buffer zu kopieren:
char* MyBuffer = new char[ AllData.Length() + 1 ];
strcpy( MyBuffer, AllData.c_str() );
"Übrigens ist c_str()[i] sehr wohl korrekt (ja ich weiß c/c++ ist nicht einfach) und zum weiteren schließe ich damit von meiner Seite die geradezu lächerliche Diskussion ab, zumal das eigentliche Anliegen offenbar ganz verlorengegangen ist.
Tschüß
Gerhard
-
Das eigentliche Anliegen ist nicht verloren gegangen sondern schon erledigt
Dank Rincewind, der mir eigentlich nur gesagt hat, "nimm ein Zeichen ganz ohne Konvertierung ausm AnsiString, caste das nach int und es klappt".So einfach kann die Welt sein :-)))
-
Gerhard schrieb:
Was Du da als Beispiel anführst, hat nichst aber auch gar nichts mit der Schleife
for (int i=0;i<=AllData.Length();i++){
z = AllData.c_str()[i]; }
zu tun.Hat es in der Tat nicht und habe ich auch nicht behauptet. Mir ging es allein darum, zu illustrieren, dass der von c_str() gelieferte Zeiger eben nur im Moment der Übergabe gültig ist.
Die, was nicht komisch ist, immer wieder funktionieren wird !
Logischerweise, da ja in jedem Schleifendurchlauf eine neue Abfrage/Übergabe erfolgt. Das hat nichts mit der von dir behaupteten Gültigkeit zu tun.
mein Hinweis:
"Solltest Du einen persistenten Pointer benötigen, ist es besser den String in einen seperaten Buffer zu kopieren
... steht im Widerspruch zu deiner o.g. Behauptung, der Zeiger wäre gültig " innerhalb deiner Anweisung. In diesem Fall der for-Schleife".
Und es ist nicht nur "besser", den String zu kopieren, sondern zwingend erforderlich. Zumindest dann, wenn man an zuverlässigen Resultaten interessiert ist.Übrigens ist c_str()[i] sehr wohl korrekt
Siehe oben, ich habe nicht bestritten, dass das funktioniert und zulässig ist. Korrekt im Sinne von "üblich", weil effizienter, ist der direkte Zugriff auf str[i].
Was rincewinds Vorschlag betrifft: der explizite Cast nach int ist unnötig.
int i = str[n];
-
Hi,
@jansen
jop da haste recht, explizit casten ist in diesem fall unnötig, weil standardumwandlung. find es aber generell besser lesbar (ok in disem speziellen fall ....) is aber meine persönliche meinung und kein grund für 'ne prügelei
-
rincewind schrieb:
kein grund für 'ne prügelei
Ein Glück, ich hab ja schon mit Gerhard alle Hände voll zu tun.