Does anyone know how to read the contents of a binary file into a static struct array, that can then be searched like a normal array?

Dani AI

Generated

Short answer: yes. Define a fixed-layout struct for each record, open the file in binary mode, load all records into memory (either in one bulk fread if the file size is known, or record-by-record into a growing array), then search the in-memory array the same way as any other array. was right to point at fread/fwrite; ’s question about members is important — use fixed-size fields so each record has a predictable size.

Example (bulk read via file size):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char username[48];
    char password_hash[64]; /* store a hash, not plaintext */
} account_t;

FILE *f = fopen("accounts.bin", "rb");
fseek(f, 0, SEEK_END);
long bytes = ftell(f);
size_t count = bytes / sizeof(account_t);
rewind(f);

account_t *users = malloc(count * sizeof *users);
size_t got = fread(users, sizeof *users, count, f);
/* check got == count, handle errors */

If the file size is unknown or records may vary, read record-by-record and realloc a buffer:

account_t tmp;
account_t *users = NULL;
size_t n = 0;
while (fread(&tmp, sizeof tmp, 1, f) == 1) {
    account_t *p = realloc(users, (n+1) * sizeof *users);
    users = p;
    users[n++] = tmp;
}

Practical cautions and tips:

  • Verify sizeof(account_t) matches the writer’s layout. If different compilers/platforms are involved, struct padding/endianness breaks binary compatibility. Prefer fixed-width fields or a portable serialization format for long-term storage.
  • Always check fopen/fread/fwrite/realloc return values and handle partial reads.
  • Strings stored in fixed char arrays must be null-terminated when written and read; use strncpy and set the last byte to '\0'.
  • For searching, a simple linear strcmp loop is easiest; use qsort+bsearch only if the array is sorted and stable.
  • Never store plaintext passwords. Store salted hashes (bcrypt/PBKDF2/Argon2) instead.

This expands on the thread: use a fixed record layout and either the ftell/fread bulk pattern or the safe record-by-record growth pattern above to get an in-memory array that can be searched like any other.

Recommended Answers

All 7 Replies

An array of structures with what members?

If you do not know the format of the binary file about the best you can do is read it into an array of char.

Well, yeah. It's basically a binary file which acts as a database of users. So it will contain usernames and passwords. My current code goes like this:

static struct account users[] = {
    {"root", "0426"}
};

And the program matches the user "root", to the password "0426", however I would rather do this with binary files.

So the struct will need two members, something like:

struct mystruct {
  char name[20];
  char passwrd[10];
}

Before main(), then in main(), create the struct itself:

struct mystruct mine[20];

and now you have an array of twenty records. Pass mine around like any other array, to your other functions, and remember, at that point, mine is a pointer, not a full array (but you can modify it's members that way).

I understand this, but how would I read a binary file into the array?

fread() to read binary records
fwrite() to write binary records

Want an example of fread()?

Back in a sec.

I know how to read and write binary records as my program does this already, I am just confused as to how to read it directly into an array which can be searched.

Ah! OK, well, obviously in a while loop:

i=0;
while(1) {
   if(fread(&myArrayName[i++], sizeOfYourRecord, 1, FILE *pointer) < 2) 
     break;  //fread returns the number of record members it stored)
}
ÜÜÜÜÜÜÜ
 ÝfreadÞ   Reads data from a stream.
 ßßßßßßß

 Syntax:
   size_t fread(void *ptr, size_t size, size_t n, FILE *stream);

 Prototype in:
 stdio.h

 Remarks:
fread reads n items of data, each of length
size bytes, from the given input stream into a
block pointed to by ptr.

The total number of bytes read is (n x size).

 Return Value:
On successful completion, fread returns the
number of items (not bytes) actually read.

It returns a short count (possibly 0) on
end-of-file or error.

 Portability:
fread is available on all UNIX systems and is
defined in ANSI C.

 See Also:
  fopen    fwrite    printf    read

 Example:
 #include <string.h>
 #include <stdio.h>

 int main(void)
 {
    FILE *stream;
    char msg[] = "this is a test";
    char buf[20];

    if ((stream = fopen("DUMMY.FIL", "w+"))
        == NULL)
    {
       fprintf(stderr, "Cannot open output file.\n");
       return 1;
    }

    /* write some data to the file */
    fwrite(msg, strlen(msg)+1, 1, stream);

    /* seek to the beginning of the file */
    fseek(stream, SEEK_SET, 0);

    /* read the data and display it */
    fread(buf, strlen(msg)+1, 1, stream);
    printf("%s\n", buf);

    fclose(stream);
    return 0;
 }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.