Help - ReadData()
-
TerryHough
- Enthusiast

- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
Help - ReadData()
I have a file created in another language consisting of multiple 700 byte
records.
I need to read each record into a sting in order to do some manipulation.
But, ReadString() doesn't work because the record contains null bytes.
So, I guess I can use ReadData() to get the 700 bytes into memory.
How can I then get that data into a string where I can use it.
Any code example will be appreciated.
TIA
Terry
records.
I need to read each record into a sting in order to do some manipulation.
But, ReadString() doesn't work because the record contains null bytes.
So, I guess I can use ReadData() to get the 700 bytes into memory.
How can I then get that data into a string where I can use it.
Any code example will be appreciated.
TIA
Terry
- tinman
- PureBasic Expert

- Posts: 1102
- Joined: Sat Apr 26, 2003 4:56 pm
- Location: Level 5 of Robot Hell
- Contact:
Re: Help - ReadData()
Something like this would work:TerryHough wrote:So, I guess I can use ReadData() to get the 700 bytes into memory.
How can I then get that data into a string where I can use it.
Any code example will be appreciated.
Code: Select all
Dim buffer.b(700)
; Open file etc
ReadData(@buffer(), 700)
my_string.s = PeekS(@buffer(offset), length)
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
(WinXPhSP3 PB5.20b14)
-
TerryHough
- Enthusiast

- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
Re: Help - ReadData()
Thanks for your reply and your idea is good, but it does not solve my
problem.
bytes long.
ReadData(@buffer(), 700) appears to stop at the first hex 00 (Nul) which
is at position 297.
I would have expected that of my_string.s = ReadString(), but not ReadData(....)
Even a For...Next loop using ReadByte() and trying to put the Nul value
into the string fails for me.
I know that a string containing Nul values is probably foreign to PB since
it uses it as the string delimiter. But in my case, Nul values appear in the
string because it has Binary Coded Decimal fields embedded. They
almost always have up to 7 $00 (Hex 00) positions. I have to be able
to read these fields in order to interpret them. So far I am failing evey
attempt.
Thanks for your efforts, and let me know if you have a different idea.
Terry
problem.
I really need to get the entire 700 bytes into a string defined as 700tinman wrote:Code: Select all
Dim buffer.b(700) ; Open file etc ReadData(@buffer(), 700) my_string.s = PeekS(@buffer(offset), length)
bytes long.
ReadData(@buffer(), 700) appears to stop at the first hex 00 (Nul) which
is at position 297.
I would have expected that of my_string.s = ReadString(), but not ReadData(....)
Even a For...Next loop using ReadByte() and trying to put the Nul value
into the string fails for me.
I know that a string containing Nul values is probably foreign to PB since
it uses it as the string delimiter. But in my case, Nul values appear in the
string because it has Binary Coded Decimal fields embedded. They
almost always have up to 7 $00 (Hex 00) positions. I have to be able
to read these fields in order to interpret them. So far I am failing evey
attempt.
Thanks for your efforts, and let me know if you have a different idea.
Terry
you can't use strings for binary data
use structures or just reserve some memory
Maybe take a look at this viewtopic.php?t=2396
use structures or just reserve some memory
Maybe take a look at this viewtopic.php?t=2396
-
TerryHough
- Enthusiast

- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
@ BerikcoBerikco wrote:you can't use strings for binary data
use structures or just reserve some memory
Maybe take a look at this viewtopic.php?t=2396
I tried looking at that post earlier, but it runs together on my screen so
badly that I could not follow it. Apparently Fangles did not use the Code
tags originally. Is ther anyway to modify it to be more readable?
I appreciate your suggestion and will give it a try immediately.
Thanks,
Terry
-
TerryHough
- Enthusiast

- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
@ Berikco
Thanks, got it. That will help I hope.
@ El_Choni
You wrote
the actual data in those fields.
For example, I know that position 296 - 303 of the 700 byte record
contains a BCD field. In hex it contains 1553000000000043 which
represents a value of 155.30. If it were negative it would contain
15530000000000C3 to represent -155.30.
I must be doing something wrong since I haven't gotten more than the
first two bytes myself. Guess I will keep on working.
Thanks for your reply and any advice.
Terry
Thanks, got it. That will help I hope.
@ El_Choni
You wrote
It probably works OK, but so far I haven't been successful getting toReadData works ok, but you must translate those BCD to ASCII before using PeekS.
the actual data in those fields.
For example, I know that position 296 - 303 of the 700 byte record
contains a BCD field. In hex it contains 1553000000000043 which
represents a value of 155.30. If it were negative it would contain
15530000000000C3 to represent -155.30.
I must be doing something wrong since I haven't gotten more than the
first two bytes myself. Guess I will keep on working.
Thanks for your reply and any advice.
Terry
-
TerryHough
- Enthusiast

- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
I have used both a byte array and a structure. Currently I am using a
structure after reading Berikco's thread.
Still the same results. I swear it appears that ReadData stops when it
hits the first NUL byte.
I will see what I can do with AllocateMemory.
Thanks,
Terry
structure after reading Berikco's thread.
Code: Select all
ReadData(@recbuf, 700) ; Read record to bufferhits the first NUL byte.
I will see what I can do with AllocateMemory.
Thanks,
Terry
I dont think so, just put this line after the ReadData()TerryHough wrote:I have used both a byte array and a structure. Currently I am using a
structure after reading Berikco's thread.
Still the same results. I swear it appears that ReadData stops when itCode: Select all
ReadData(@recbuf, 700) ; Read record to buffer
hits the first NUL byte.
I will see what I can do with AllocateMemory.
Thanks,
Terry
Code: Select all
Debug Loc()-
TerryHough
- Enthusiast

- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
Hmm, if i'm not wrong, you don't need floats here, as BCD numbers are
only whole numbers.
Somethink like this should make a normal Number out of a byte stores in BCD:
BCD just means, that each digit of a decimal number is stored in 4 bits,
so one byte in BCD can hold numbers from 0-99 (2 digits, which use 4 bits)
Hope this helps... (tell me, if not
)
Timo
only whole numbers.
Somethink like this should make a normal Number out of a byte stores in BCD:
Code: Select all
BCD.l = PeekB(...) & $FF; read byte out of memory and make it unsigned
DecimalNumber.l = (BCD >> 4)*10 + (BCD & $F) ; convert to usual format
so one byte in BCD can hold numbers from 0-99 (2 digits, which use 4 bits)
Hope this helps... (tell me, if not
Timo
quidquid Latine dictum sit altum videtur
-
TerryHough
- Enthusiast

- Posts: 781
- Joined: Fri Apr 25, 2003 6:51 pm
- Location: NC, USA
- Contact:
Thanks for your reply Freak!freak wrote:Hmm, if i'm not wrong, you don't need floats here, as BCD numbers are
only whole numbers.
--- snip ----
BCD just means, that each digit of a decimal number is stored in 4 bits,
so one byte in BCD can hold numbers from 0-99 (2 digits, which use 4 bits)
Hope this helps... (tell me, if not)
I can's speak for all languages or standards but at least in the language
I have been writing in for over 20 years BCD fields are not limited to
whole numbers.
BCD fields are not limited to one byte. And the final byte of the field
carries the sign and number of significan places to the left of the
decimal. The length of the BCD field is determined by the number of
digits of precision desired. For example, an 8 byte BCD field would
allow 14 digits of precision. The precision is controlled by a program
global parameter specifing the number of digits of precision from 4 to
14.
Example shown as 8 Hex bytes:
32 64 12 34 00 00 00 00 44
represents the real number 3264.1234 since the last byte shows the value
to be postive and the decimal position is after the 4th position.
12 35 45 00 00 00 00 00 43
represents the real number 123.45
This language does math using these "real" BCD numbers completely
accurately. (Don't ask me how, I don't know. I just know is absolutely
reliable!)
Since I primarily write financial applications this is very
important to me. I must be able to store the actual values.
Again an example: A = 1 / 3 results in .333333333333333 which stores
as in Hex 33 33 33 33 33 33 33 33 40
B = 25 / 2 results in 12.5 stored as in Hex 12 50 00 00 00 00 00 42
A typical float value in PB only can approximate that, right?
For financial apps, that means I can store values up to
$999,999,999,999.99 in 8 bytes
This BCD representation allows me to accurately store numbers in
the same amount of space that a PB float value takes. But, try storing
123.45 in a float, and then get that exact value back.
My current project (hopefull can be done in PB) requires me to use
data created and stored by that language, so I must be able to "translate"
these BCD fields accurately. I am almost there, but ran into a slight
hitch (see post viewtopic.php?t=6524 for
details) that prevents more than 10 digits of precision.
If you have any ideas, please let me know. And thanks for your usual
great ideas and suggestions on the forum.
Terry
See, that's why i said "Hmm, if i'm not wrong..."
I have only been in contact with BCD numbers once, and that were
whole, single-byte number. But hey, I never stop learning....
Based on your description, i wrote this one:
You pass this procedure the Memory address of a BCD number, and
the length in bytes of it. However, as you can see in the examples, it is
not very accurate. I'm trying to make it somehow better.
Timo
I have only been in contact with BCD numbers once, and that were
whole, single-byte number. But hey, I never stop learning....
Based on your description, i wrote this one:
Code: Select all
Procedure.f BCD2Float(Memory.l, Length.l)
DefType.l decimal, digit, divisor, addition
DefType.f Result
decimal = PeekB(Memory+Length-1) & %111111
For digit = 1 To decimal
Result * 10
If digit & 1
addition = (PeekB(Memory+(digit/2)) >> 4)
Else
addition = (PeekB(Memory+(digit/2)-1) & $F)
EndIf
Result + addition
Next digit
divisor.l = 1
For digit = decimal+1 To (Length-1)*2
divisor * 10
If digit & 1
addition = (PeekB(Memory+(digit/2)) >> 4)
Else
addition = (PeekB(Memory+(digit/2)-1) & $F)
EndIf
Result + addition / divisor
Next digit
If PeekB(Memory+Length-1) & %10000000
Result * (-1)
EndIf
ProcedureReturn Result
EndProcedure
Debug BCD2Float(?Number1, 8)
Debug BCD2Float(?Number2, 8)
Debug BCD2Float(?Number3, 8)
Debug BCD2Float(?Number4, 8)
DataSection
Number1: Data.b $32, $64, $12, $34, $00, $00, $00, $44 ; 3264.1234
Number2: Data.b $12, $35, $45, $00, $00, $00, $00, $43 ; 123.45
Number3: Data.b $33, $33, $33, $33, $33, $33, $33, $40 ; 1/3
Number4: Data.b $12, $50, $00, $00, $00, $00, $00, $42 ; 25/2
EndDataSectionthe length in bytes of it. However, as you can see in the examples, it is
not very accurate. I'm trying to make it somehow better.
Timo
quidquid Latine dictum sit altum videtur
