Problem mit ASCII Zeichen



  • Ich muss eine Datei mit Borland Builder 4.0 erzeugen um diese dann mit einem anderen Programm einlesen zu können. Eine Programmvorlage habe ich schon bei einem Basic-Programm gesehen. Dort gibt es folgende Definition:

    type Datensatz
    	Prüfernummer    as string * 6
    	Typ             as string * 2
    	Auftragsnummer  as string * 11
    	Merkmalnummer   as string * 5
    	Datum           as string * 11
    	Zeit            as string * 9
    	Meßwert         as string * 15
    end type
    

    Jeder der oben definierten Variablen wird mit einem CHR(0) abgeschlossen
    z.B.: Eintrag.Prüfernummer= ,,12345" & CHR(0).

    So nun habe ich einen String welche ich dann als Char umwandle mit der entsprechenden Länge und später überall ein '\0' anhänge.

    Nachdem ich die erzeugte Datei mit einem Hexeditor anschaue habe ich folgenden Effekt:

    Bei der Basic-Datei steht an entsprechender Stelle wie gefordert "00".
    Bei meinem Programm steht eine "42"!

    Wo liegt mein Fehler??? 😞

    Edit:
    Zur Textformatierung bitte die Code-Tags benutzen.



  • Immer noch das gleiche Problem wie in Deinem ersten Posting.

    Schau Dir nur mal von z.B. TMemo die Eigenschaft OEMConvert an...



  • Statt des VB-Codes solltest du uns lieber deinen eigenen Code zeigen. Das macht es erheblich einfacher, eventuelle Fehler darin aufzudecken. 😉



  • Maik Vogt schrieb:

    Jeder der oben definierten Variablen wird mit einem CHR(0) abgeschlossen
    z.B.: Eintrag.Prüfernummer= ,,12345" & CHR(0).
    (...)
    Bei der Basic-Datei steht an entsprechender Stelle wie gefordert "00".
    Bei meinem Programm steht eine "42"!

    Wo liegt mein Fehler??? 😞

    Hast Du Dir schon mal angesehen, was Chr(0) eigentlich macht - oder hast Du keine MSDN?
    Schau Dir auch mal an, welchem Zeichen der ASCII-Code 42 entspricht. 😉

    Gruß,

    Alexander



  • Hallo!

    Eintrag.Prüfernummer= ,,12345" & CHR(0).

    Warum verbindest du 2 Strings eigentlich mit dem & operator???

    ...was mir dabei einfällt: Wahrscheinlich ist die Antwort auf alle Fragen tatsächlich 42 🙂

    tschüss
    Robert



  • OK. ZUM ALLERLETZTEN MAL DER HINWEIS:

    Man sollte derartige Manipulationen der String-Klassen unterlassen!!!! Ein String besteht nicht nur aus einer Zeichenkette, da ist eine komplette Speicherverwaltung mit dabei. Wenn man nicht genau weiß, an welchen Schrauben man drehen muß, sollte man das tunlichst lassen.

    Allerdings liefert

    Eintrag.Prüfernummer.c_str();
    

    eine Zeichenkette, bei der das \0 bereits gratis und ohne Verrenkungen bereits mit dran ist. Allerdings muß er sich dann noch mit der Lese- und Schreibroutine befassen, da das nicht mehr über TKomponente::SaveToFile() geht.


  • Mod

    Hallo

    die hunderten von Beitraegen zum Thema .c_str() kennst du oder ?

    sollte man sehr sehr vorsichtig damit sein

    Warum sollte man AnsiStrings nicht mit & aneinanderhaengen
    (ich weis, das das eine Klasse ist)
    aber das ist doch gerade der grosse Vorteil gegenueber char*

    MfG
    Klaus



  • Hallo!

    Weil & bei mir nicht funktioniert und lt. Headerdatei und Doku der Operator & bei der AnsiString-Klasse auch nicht überladen ist.

    Außerdem ist der & operator der Adress-Operator, damit bekommst du die Speicheradresse des Strings raus, wenn du z.B.
    AnsiString *String2= &String1;
    machen willst.

    Bei mir funktioniert zumindest das hier nicht:

    AnsiString  test1 = "a", test2 = "b";
    ShowMessage(test1&test2);
    

    Also sollte man zum aneinanderhängen von Strings den + operator verwenden, weil dieser dafür gedacht ist, und auch funktioniert 🙂

    tschüss
    Robert



  • rowisoft schrieb:

    Eintrag.Prüfernummer= ,,12345" & CHR(0).

    Warum verbindest du 2 Strings eigentlich mit dem & operator???

    Vielleicht, weil das VB-Code ist?

    Gruß,

    Alexander



  • Danke Robert,

    und wenn sich Klaus noch mal das ursprüngliche Posting ansieht, wird er feststellen, dass Maik INNERHALB eines AnsiStrings mehrere \0 haben will (darauf läuft es hinaus).

    Und das machen die Stringklassen einfach nicht mit. Die Länge des Strings wird zwar weiterhin korrekt angezeigt, aber alle Ausgabeoperationen enden beim ersten vorkommen von \0 im String. Seufz.



  • Hallo Joe!

    Das mit dem Nullbyte ist mir schon klar, dass das nicht funktioniert, das habe ich ja auch nicht bezweifelt.
    Ich habe lediglich geschrieben, weil mir die Sache mit dem & operator so ins Gesicht gesprungen ist, dass ich mir dachte "was soll das denn?"

    Aber wenn das dann VB Code ist, hat sich die Sache eh erledigt...

    Zum Thema mit \0 in Strings, habe ich hier im Forum auch schon einmal ein Posting gesehen. Dort wollte wohl irgendjemand den String wieder der Reihe nach auslesen, der \0 en enthalten hat. Hat natürlich nicht funktioniert.

    Im übrigen wird auch über die Funktion .Length() nicht die korrekte Länge des Stringinhalts ausgegeben, sondern wieder lediglich nur bis zum Nullbyte!
    (verwendet intern wahrscheinlich auch nur die Funktion strlen oder so...)

    tschüss
    Robert



  • Folgende Testroutine:

    AnsiString test; 
    	test = "Hallo"; 
    	Memo1->Lines->Add(test); 
    	Memo1->Lines->Add(AnsiString(test.Length())); 
    	test[test.Length()] = 0; 
    	Memo1->Lines->Add(test); 
    	Memo1->Lines->Add(AnsiString(test.Length())); 
    	test += "xxx"; 
    	Memo1->Lines->Add(test); 
    	Memo1->Lines->Add(AnsiString(test.Length()));
    

    ergibt folgende Ausgabe im Memo:
    Hallo
    5
    Hall
    5
    Hall
    8



  • Hallo!

    Ich habs ausprobiert mit:
    String test = "Hall\0o du da";
    ShowMessage(IntToStr(test.Length());

    und da wird 4 zurückgegeben. Kann aber evtl. auch daran liegen, dass zur Compilzeit der Rest des Strings abgeschnitten wird, oder die Zuweisung später nur bis zum Nullbyte in die chars kopiert.

    tschüss
    Robert



  • rowisoft schrieb:

    Kann aber evtl. auch daran liegen, dass zur Compilzeit der Rest des Strings abgeschnitten wird

    Korrekt. Meine Version 'manipuliert' den String zur Laufzeit. Deshalb das unterschiedliche Ergebnis.

    Grüße Joe



  • Nur mal so eine unschuldige Frage: Warum um alles in der Welt, wollt ihr inmitten eines Strings ein Nullbyte?



  • Wir nicht, der Maik will 'mit Bodmitteln' eine Datei erstellen, bei der eine Zeile einen Datensatz darstellt in dem mehrere 'Strings' stehen, die durch ein \0 getrennt sind... Und mit Bordmitteln a la TMemo->Lines->SaveToFile() geht das eben nicht.



  • Ahja. Und funktioniert deine Lösung auch beim Speichern? Kann ich mir irgendwie nicht vorstellen. Außerdem: gehören die normalen Schreib/Lesemethoden von z.B. TFileStream nicht auch mit zu den "Bordmitteln"?



  • ja, genau das hab' ich ihm in meiner ersten Antwort zu seinem ersten Posting (er hat 2 zu dem Thema gemacht) schon geschrieben...



  • Hi,
    @Maik Vogt: Wenn Deine "Programmvorlage" es tatsächlich vorschreibt, daß Deine Variablen (Prüfnummer, Typ u.s.w.) durch ein 0-Byte voneinander getrennt werden müssen, macht die Verwendung der AnsiString-Klasse keinen Sinn, was in diesem Thread bereits zur Sprache kam. Das ist aber nicht weiter tragisch, da Deine Record-Struktur recht einfach aussieht.
    Hier ein Vorschlag (ungetestet und es geht sicherlich weitaus eleganter):

    char record[6 + 1 + 2 + 1 + 11 + 1 + 5 + 1 + 11 + 1 + 9 + 1 + 15 + 1];
    String pruefernummer = "123456";
    String typ = "78";
    int offset = 0;
    for (int i=0; i < pruefernummer.Length(); i++)
    {
        record[i] = pruefernummer[i + 1];
    }
    record[6] = '\0';
    offset = 7;
    for (int i=0; i < typ.Length(); i++)
    {
        record[offset + i] = typ[i + 1];
    }
    record[9] = '\0';
    //u.s.w....
    


  • @dschnesky:

    Heißt Du zufällig Jan mit Vornamen?


Anmelden zum Antworten