Well, since it's binary, you need to know the structure of the file first. It is very difficult to guess based on the file contents only, so don't ask me.
When you do, define a C structure which corresponds to the binary data. For example,
Code:
#include <stdint.h>
struct data_file {
int32_t identifier;
int16_t something[6];
int8_t other[12];
/* ... */
}
Use int
N_t and uint
N_t types from C99
stdint.h, so that your code is portable.
(If the structure has a suitable identifier, its easy to make this even byte order independent -- but that's not important here.)
I recommend using a function to read the data file, something like this:
Code:
#include <errno.h>
#include <stdio.h>
int read_data_file(const char *const filename, struct data_file *const data)
{
FILE *handle;
/* Invalid parameters? */
if (!filename || !data) {
errno = EINVAL;
return -1;
}
/* Open file in binary mode (in Linux "b" is irrelevant) */
handle = fopen(filename, "rb");
if (!handle)
return -1;
/* Verify file length matches the structure exactly. */
if (fseeko(handle, (off_t)0, SEEK_END)) {
const int saved_errno = errno;
fclose(handle);
errno = saved_errno;
return -1;
}
if (ftello(handle) != (off_t)sizeof(struct data_file)) {
fclose(handle);
errno = EBADF; /* Closest to "File has bad length". */
return -1;
}
rewind(handle);
/* Read the data structure */
if (fread(data, sizeof(struct data_file), 1, handle) != 1) {
fclose(handle);
errno = EBADF; /* Closest to "File has bad format" */
return -1;
}
/* Close file. Note delayed read errors. */
if (fclose(handle))
return -1;
return 0;
}
You can leave out the file length check, but I recommend doing some kind of verification that the file is a configuration file. Almost all binary files have some kind of identification block near the beginning of the file. Note: errno is the standard way to report errors to callers; this reuses EBADF ("Bad file descriptor") to tell that the file does not look like a proper configuration file.
Then, in your program, you can simply call the function:
Code:
int main(void)
{
struct data_file my_data;
const char *my_data_file_name = "/tmp/config.cng";
/* Read the config file; print an error and exit if any problems. */
if (read_data_file(my_data_file_name, &my_data)) {
fprintf(stderr, "%s: %s.\n", my_data_file_name, strerror(errno));
exit(1);
}
/* Okay, got my_data. */
printf("identifier = ", my_data.identifier);
printf("other = 0x%04x 0x%04x ... 0x%04x\n", my_data.other[0], my_data.other[1], my_data.other[11]);
return 0;
}
Hope this helps,
Nominal Animal