Seite 1 von 2

Write/ReadQuad(PROBLEM) [GELÖST]

Verfasst: 27.04.2008 20:10
von Tompazi
Hi, ich habe folgendes problem: Ich möchte in eine Datei entweder 2 Quads oder 2 Quads und einen String schreiben.
Wenn der erste Quad 1000 ist steht ein String in der Datei.
der 2te Quad ist immer 1 oder 0.
Das ganze soll ich wieder auslesen.

Das Problem: Wenn ich eine Datei mit String habe ist der 2te Quad immer 0 auch wenn er 1 sein sollte. liegt das Problem beim erstellen oder beim auslesen?

Erstellung:

Code: Alles auswählen

   
;...
 If GetGadgetState(14) = 0
     CreateFile(1,"StandardKey")
     OpenFile(1,"StandardKey")
     WriteQuad(1,CodeKey)
     If DoubleChar = 1
      WriteQuad(1,1)
     Else
      WriteQuad(1,0)
     EndIf
     CloseFile(1)
    Else
     CreateFile(1,"StandardKey")
     OpenFile(1,"StandardKey")
     WriteQuad(1,1000)
     WriteString(1,file2$)
     If DoubleChar = 1                        ;FEHLER
      WriteQuad(1,1)                           ; Hier
     Else                                            ; irgendwo?
      WriteQuad(1,0)
     EndIf
     CloseFile(1)
    EndIf
;...
Auslesung:

Code: Alles auswählen

 
;...
If OpenFile(1,"StandardKey")
  Key = ReadQuad(1)
   If Key = 1000
    file2$ = ReadString(1)
    SetGadgetState(14,1)
    If OpenFile(2,file2$)
    For m = 0 To 255
    MyChar(m) = ReadQuad(2)
    Next m
    CloseFile(2)
    EndIf
   Else
    SetGadgetState(8,Key)
   EndIf
  Double = ReadQuad(1)
  Debug Double
  SetGadgetState(10,Double)
  CloseFile(1)
 Else
  SetGadgetState(8,127)
 EndIf
;...
MfG Tompazi

Verfasst: 27.04.2008 20:24
von NicTheQuick
Wieso erstellst du die Datei zuerst und öffnest sie dann nochmal? Einmal
sollte reichen.
Und die Rückgabewerte testen wäre auch eine gute Idee. Vielleicht lag es
schon daran.

Code: Alles auswählen

;...
If GetGadgetState(14) = 0
  If CreateFile(1,"StandardKey")
    WriteQuad(1,CodeKey)
    If DoubleChar = 1
      WriteQuad(1,1)
    Else
      WriteQuad(1,0)
    EndIf
    CloseFile(1)
  EndIf
Else
  If CreateFile(1,"StandardKey")
    WriteQuad(1,1000)
    WriteString(1,file2$)
    If DoubleChar = 1                        ;FEHLER
      WriteQuad(1,1)                           ; Hier
    Else                                            ; irgendwo?
      WriteQuad(1,0)
    EndIf
    CloseFile(1)
  EndIf
EndIf
Falls der Fehler dann immer noch bestehen sollte, versuch mal vor dem 'ReadString(1)' noch ein 'ReadCharacter(1)' einzufügen.

'ReadString()' und 'WriteString()' sind nicht für Binärdaten gedacht.
Deswegen glaube ich, dass der Dateizeiger nach dem 'ReadString(1)' auf
dem Nullcharacter steht und das nachfolgende 'ReadQuad(1)' dann das
letzte Byte nicht mehr liest.


Als Alternative zu 'ReadString()' und 'WriteString()' würde ich aber eher
sowas hier empfehlen:

Code: Alles auswählen

Procedure WriteStringBB(File.l, Text.s)
  WriteLong(File, Len(Text))
  WriteString(File, Text)
EndProcedure

Procedure ReadStringBB(File.l)
  Protected length.l, text.s = ""
  
  length = ReadLong(File)
  If length
    text = Space(length)
    length * SizeOf(Character)
    ReadData(File, @text, length)
  EndIf
  
  ProcedureReturn text
EndProcedure

Verfasst: 27.04.2008 22:10
von Tompazi
'ReadString()' und 'WriteString()' sind nicht für Binärdaten gedacht.
Deswegen glaube ich, dass der Dateizeiger nach dem 'ReadString(1)' auf
dem Nullcharacter steht und das nachfolgende 'ReadQuad(1)' dann das
letzte Byte nicht mehr liest.
ich schreibe mit WriteString() keine Binärdaten sondern einen Dateipfad.

also ich hab Quad String Quad
z.B. 1000 C:\Datei 1
Ich habe einmal nach geschaut in der datei es wird schon als 0 (bzw. viele Spaces )
geschrieben.

Was mich irritiert ist das es bei GetGadgetState(14) = 0 also ohne String funktioniert und mit nicht.

ich kann da aber nicht sehen warum!!

Code: Alles auswählen

    If GetGadgetState(14) = 0
      If CreateFile(1,"StandardKey")
      WriteQuad(1,CodeKey)
      If DoubleChar = 1
       WriteQuad(1,1)
      Else
       WriteQuad(1,0) 
      EndIf
      CloseFile(1)
     EndIf
    Else 
     If CreateFile(1,"StandardKey")
      WriteQuad(1,1000) 
      WriteString(1,file2$)
      If DoubleChar = 1 ;Funktioniert (?)
       WriteQuad(1,1) ;Funktioniert Nicht!!
      Else DoubleChar = 0 ;Funktioniert (?)
       WriteQuad(1,0) ;Funktioniert (?)
      EndIf
      CloseFile(1)
     EndIf
    EndIf 
Der Fehler existiert noch.

Verfasst: 27.04.2008 23:13
von NicTheQuick
Probier doch einfach mal die Procedures aus, die ich dir gepostet habe.

Verfasst: 28.04.2008 11:14
von nco2k
@Tompazi
natürlich geht es nicht, da der string nicht nullterminiert ist. entweder du speicherst die grösse vor dem string (wie die proc von nic) oder du schreibst einfach ein nullbyte nachm string:

Code: Alles auswählen

If CreateFile(1,"StandardKey")
  If GetGadgetState(14)
    WriteQuad(1,1000)
    WriteString(1,file2$)
    WriteByte(1,0); <--- so
  Else
    WriteQuad(1,CodeKey)
  EndIf
  WriteQuad(1,DoubleChar)
  CloseFile(1)
EndIf
c ya,
nco2k

Verfasst: 28.04.2008 15:18
von NicTheQuick
Besser 'WriteCharacter()' anstatt 'WriteByte()' für Unicode.

Ist jetzt nicht wichtig für Anfänger, aber gut zu wissen für jeden, der diesen
Thread mal über die Suche findet.

Verfasst: 28.04.2008 20:43
von nco2k
NicTheQuick hat geschrieben:Besser 'WriteCharacter()' anstatt 'WriteByte()' für Unicode.
nope, falls es eine unicode exe ist, schreibt WriteString() automatisch im UTF8 format, sofern nicht anders angegeben und dort ist die nullterminierung ebenfalls nur 1byte lang, so wie bei ascii:
Help hat geschrieben:Without any 'Flags', the string is written in UTF8 format if the program is compiled in unicode mode, else it's written in ASCII format.
ansonsten wär das vielleicht für den einen oder anderen hilfreich, für einen leichteren unicode einstieg:

Code: Alles auswählen

Procedure WriteStringNullByte(File, Format=-1);specifies the end of a string 
  If Format = -1 
    Select SizeOf(Character) 
      Case 1 
        Format = #PB_Ascii 
      Case 2 
        Format = #PB_UTF8 
    EndSelect 
  EndIf 
  Select Format 
    Case #PB_Ascii, #PB_UTF8 
      WriteByte(File, 0) 
    Case #PB_Unicode 
      WriteWord(File, 0) 
  EndSelect 
EndProcedure 

Procedure BOMSize(Format=-1);returns the size in byte of a BOM (Byte Order Mark) 
  If Format = -1 
    Select SizeOf(Character) 
      Case 1 
        Format = #PB_Ascii 
      Case 2 
        Format = #PB_UTF8 
    EndSelect 
  EndIf 
  Select Format 
    Case #PB_Ascii 
      Result = 0 
    Case #PB_Unicode 
      Result = 2 
    Case #PB_UTF8 
      Result = 3 
  EndSelect 
  ProcedureReturn Result 
EndProcedure 

FileName.s = "C:\Test.txt" 
Format = #PB_Unicode 

FileID = CreateFile(#PB_Any, FileName) 
If FileID 
  
  WriteStringFormat(FileID, Format) 
  
  WriteString(FileID, "TestA", Format) 
  WriteStringNullByte(FileID, Format) 
  
  WriteString(FileID, "TestB", Format) 
  WriteStringNullByte(FileID, Format) 
  
  WriteString(FileID, "TestC", Format) 
  WriteStringNullByte(FileID, Format) 
  
  FileSeek(FileID, BOMSize(Format)) 
  Debug ReadString(FileID, Format) 
  Debug ReadString(FileID, Format) 
  Debug ReadString(FileID, Format) 
  
  CloseFile(FileID) 
  DeleteFile(FileName) 
EndIf
c ya,
nco2k

Verfasst: 29.04.2008 13:11
von Brügge
hiho

ist zwar nicht so ganz mein gebiet, aber ich hoffe ich kann helfen.

so wie ich das verstanden habe möchtest du eine Zahl, dann einen string und wieder eine Zahl in eine Datei abspeichern oder?

dann erstelle doch einfach einen string und schreibe dort alles hinein. du kannst es auch mit sonderzeichen trennen und über stringfeld() trennen und mit hilfe von Val() zu einer Zahl machen.

hoffe ich konnte dir helfen ^^

Verfasst: 29.04.2008 13:55
von Tompazi
Danke, funktioniert jetzt.

Ich hab das mit dem WriteByte(1,0) gemacht.

trotzdem funktioniert etwas anderes nicht was mir vorher garnicht aufgefallen ist.

Der String ist der Pfad der Datei die man auch so öffnen kann.
Das hier funktioniert:

Code: Alles auswählen

    If GetGadgetState(14) = 1
     file2$ = OpenFileRequester("Select a key","key1.key",".key | *.key",0)
     If file2$
      OpenFile(1,file2$)
      For m = 0 To 255
       MyChar(m) = ReadQuad(1)
      Next m
      CloseFile(1)
      EndIf
    EndIf
Diese einstellungen werden in einer Datei namens "StandardKey" gespeichert. Beim Starten des Programmes wird dann das ausgeführt:

Code: Alles auswählen

;...
If OpenFile(1,"StandardKey")
  Key = ReadQuad(1)
   If Key = 1000
    file2$ = ReadString(1)
    SetGadgetState(14,1)
    If OpenFile(2,file2$)                    ; Fehler 
     For m = 0 To 255                        ; Vielleicht
      MyChar(m) = ReadQuad(2)                ; hier
     Next m                                  ; oder
     CloseFile(2)                            ; hier irgendwo?
    EndIf
   Else
    SetGadgetState(8,Key)
   EndIf
   Double = ReadQuad(1)
   Debug Double
   SetGadgetState(10,Double)
  CloseFile(1)
 Else
  SetGadgetState(8,127)
 EndIf
;...
Ich komme trotzdem nicht zu dem gelichen Ergebnis und kann MyChar() nicht benützen.

MfG Tompazi

Verfasst: 29.04.2008 15:01
von Kiffi
eine beliebte Fehlerquelle ist, den Dateipfad relativ anzugeben. Daraus
ergibt sicht, dass das Kompilat (abhängig davon, ob man es in der IDE oder
mit Doppelklick auf die EXE startet) in unterschiedlichen Pfaden sucht.

Obiges in Verbindung mit OpenFile() (anstelle des besser geeigneten
ReadFile()) kann zu Fehlern führen, denen man schwer auf die Schliche
kommt.

Grüße ... Kiffi