0
votes

I'm currently working on a DBF file manager and I'm having some problems...

One of the elements that compose the header is the last date that the file was updated. The problem is: the field format is YYMMDD and it MUST have 3 bytes.

How is it possible to write a date using that format using only 3 bytes? Also, another field represents the type of the file (if it have a memo or not).

The file type in my case is 03h and this field MUST use only 1 byte. I'm pretty confused.

2
Well, think about how many different numbers can be represented with a single byte: 256. So, you can store any 2 (decimal) digit number (0-99) inside a single byte, with plenty of room to spare. Does this help?Cameron
I think i got the idea but how do I do it? I was using putc without sucessCelso Shigaki
What went wrong with putc?twin
I was not sure how to do it so I used putc to write the date, char by char. Is that wrong?Celso Shigaki
Chars take one byte each. So if you need to write 3 bytes exactly, you need to write a number which has the composition that you want. See my answer below. I hope I'm not misunderstanding your need.webuster

2 Answers

1
votes

I would hold your data in 3 bytes as

  • first byte = year
  • second byte = month
  • third byte = day

There's plenty of room in each byte for the domain of each field (year, month, day). You could write them in an integer with bit-shifting operations, like this:

int year = 13;
int month = 7;
int day = 26;
int my_date = (year << 16) | (month << 8) | day;

Edit:

What I did in my_date: I basically concatenated the information you need (year, month, day) into a series of bits (8 bits per information field), as an integer. You know an int is 4 bytes. Consider for starters that my_date is 0, that is, all 32 bits are 0. The 4 bytes of it are as follows ("|" denotes concatenation; that's for ease of reading):

my_date = 0 | 0 | 0 | 0

When I write year << 16 I have

year << 16 = 0 | year | 0 | 0

In a similar fashion,

month << 8 = 0 | 0 | month | 0
day = 0 | 0 | 0 | day

When I apply the OR operator on all of them, my_date looks like this:

my_date = 0 | year | month | day

Accessing them:

year = (my_date & 0xFF0000) >> 16;
month = (my_date & 0xFF00) >> 8;
day = my_date & 0xFF;

Edit: how accessing works. We previously had

my_date = 0 | year | month | day

If you do, for example, an AND with 0xFF00, which is 0 | 0 | FF | 0, you get

my_date & 0xFF00 = 0 | 0 | month | 0

Now all you need to do is shift your data back, so

(my_date & 0xFF00) >> 8 = 0 | 0 | 0 | month = month

Hope it's clearer now.

0
votes

First byte for year: 2000 + YY. Can count from 2000 till 2255

Second byte for month: 1-12

Third byte for day: 1-31