I’ve been working on a project where I need to store bytes and integers in a file and read them back in later. The bytes were easy enough, the integers were easy too, once I found the best way. I’m only talking about words consisting of two bytes.
The first method I tried was using fprintf() and fscanf(). While this works, fscanf() needs to know how many bytes to read or a terminator. This is also wasteful, as the number is saved in ASCII form. So, a 5 digit number which takes 2 bytes of memory, ends up as 5 bytes plus a terminator once saved with fprintf().
The next method I tried was calculating the high (most significant) and low (least significant) bytes, then storing them as individual bytes using fputc(). This worked well using fgetc() to retrieve the values. The method was efficient storage wise, but came at the cost of mathmatical operations on the save and read.
The last method I tried, which turns out to be the best, is using fwrite() and fread(). In the past I primarily related these to writing and reading arrays of bytes, such as character strings, or numeric arrays. It was perhaps some knowledge I lost over the years, and just re-learned. I discovered using this method its easy to store and retrieve an integer in the storage efficient 2 byte form.
I wrote a small program to set a byte and integer, display them in various forms, write them to file, then read them back into new variables, and finally display them back in the same forms. This is done on the Atari 8 bit using CC65. Compilation instructions are in the header notes.
Here is the short program:
// ------------------------------------------------------------
// Program: numsave.c
// Desc...: Numberic write to/read from file tests
// Author.: Ripdubski
// Date...: 20220809
// Notes..: cl65 -v -t atari numsave.c -o numsave.xex
// ------------------------------------------------------------
// Pull in include files
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <atari.h>
// ------------------------------------------------------------
// Func...: void main(void)
// Desc...: Main routine
// ------------------------------------------------------------
void main(void)
{
// Declare vars
FILE *fp;
char c = 65, cb; // A, 0x41
unsigned int i = 32527, ia, ib, ir; // 0x7F0F
// Setup screen
clrscr();
printf("-[CC65 Numeric Save To File Tests]------");
// Show char array and address
printf("\nVariables:\n");
printf(" Byte: c=%c d=%d\n", c, c);
printf(" Int: d=%d x=%04x\n", i, i);
printf("Int HiLo: Hi d=%d x=%02x Lo d=%d x=%02x\n", i/256, i/256, i%256, i%256);
// Open file
fp = fopen("numsave.dat", "wb");
if (fp != NULL) {
// Write data to file
printf("\nWrite: fputc byte");
fputc(c, fp);
printf(", fwrite int");
fwrite(&i, 1, sizeof(i), fp);
printf(", hi/lo.\n");
fprintf(fp, "%c%c", i/256, i%256);
// Close file
fclose(fp);
}
else {
printf("ERROR: Could not create file!\n");
}
// Open file
fp = fopen("numsave.dat", "rb");
if (fp != NULL) {
// Read data from file
printf(" Read: fgetc byte");
cb = fgetc(fp);
printf(", fread int");
fread(&ir, 1, sizeof(ir), fp);
printf(", hi/lo.\n");
ia = fgetc(fp);
ib = fgetc(fp);
printf("\n Byte: c=%c d=%d\n", cb, cb);
printf(" Int: d=%d h=%x\n", ir, ir);
printf("Int HiLo: Hi d=%d x=%02x Lo d=%d x=%02x\n", ia, ia, ib, ib);
printf("Calc Int: d=%d h=%04x\n", (ia*256)+ib, (ia*256)+ib);
// Close file
fclose(fp);
}
else {
printf("ERROR: Could not open file!\n");
}
// Exit
return;
}
Here is a screen shot of it working, with a hexdump of the file: