UPI Study › Courses › Programming in C › Free lessons › Lesson 10.1 Free with a free account
Workshop: Saving and Restoring Structures in Binary Files
Programming in C · Chapter 10: Structures, Unions, and Compound Data ModelingSection 10.1 · lesson 64 of 787 min · free with a free account
Free preview
Create a free account to keep watching
It takes a minute and costs nothing. Your free account unlocks all of Chapter 1 and 3 more lessons of Programming in C.
Lesson complete
Earn the 3 college credits for Programming in C
Enrolling adds a quiz after each lesson, the graded work and the official transcript. Recommended for credit by NCCRS.
Next lesson: Defining Structures in C →← Workshop: A Text File Processing PipelineNext lesson: Defining Structures in C →
In this lesson
Serializing struct records to binary files with fwrite and fread.
- Explain serializing and why data in memory must be saved to a file
- Save and restore a struct or an array of structs with one fwrite and one fread
- Zero a struct before saving it and check the counts fwrite and fread return
- Explain how padding, byte order, and layout changes tie a struct file to its program
Free study notes
Get this lesson's notes by email
The key points and 4 practice questions with answers, in your inbox. One email, free.
One email. Unsubscribe in one click.
Transcript
Everything said in the video, section by section (1,033 words). Read along, or search it.
The Problem
Scores Vanish When the Program Ends
The Starlight Arcade closes at midnight, and the lights go off. In the morning, the high-score board must still show last night's heroes. But a variable lives only while its program runs. When the program ends, every score in memory is gone. So the scores must go into a file before the program ends, and come back the next time it starts. Turning data in memory into bytes you can store is called serializing. Today you'll do it with a whole player record at once.
Quick Primer
Just Enough Struct to Start
First, just enough struct. Structures get their full lesson in 10.2. This workshop needs only a tiny piece. A struct is your own bundle type: several variables, called members, stored together under one name. struct Player bundles a name of 16 characters, room for 15 letters and the end mark, with an int score. hero is one variable of that type. Writing hero dot score reaches the score inside it. Build and run: Mira, 4200. And the whole struct takes 20 bytes: 16 for the name, then 4 for the score, in one block. Because it's one block, a single fwrite can copy the whole player to a file in one go.
Step One
Saving a Player at Closing Time
Here's Priya's save program, the one that runs at closing time. It starts hero at all zeros, then fills in the name and the score. Why zeros first? The name box has 16 places, and Mira uses five, counting the end mark. Without the zeros, leftovers from memory would be saved too. Open hero.bin with w b: write, in binary. If fopen fails, it returns NULL, and the program stops. Then one fwrite: the address of hero, the size of hero, a count of one item, and the file. fwrite returns how many items it wrote. Build and run: saved one player. Then the program ends, and hero is gone.
Inside the File
Reading the Saved Bytes in Hex
The program has ended, but the file is still there. Ask how big it is: 20 bytes, exactly one struct Player. Now look inside with xxd, a tool that prints a file's bytes in hex. These options show four bytes a row. The first row is 4d 69 72 61: M, i, r, a. Then come zeros: the end mark, and the unused places of the name. The last row, from byte 16, is the score. 68 10 means hex 1068, which is 4200, stored low byte first, as in 9.9.
Step Two
Loading the Player Next Morning
Next morning, a different program starts: Priya's loader. Its variable, loaded, begins as all zeros. It uses the very same struct Player blueprint, so the bytes land in the same members. Open the file with r b: read, in binary. If there's no save file yet, say so and stop. Then one fread: where to put the bytes, the size of one item, how many items, and which file. It returns how many items it really read. Build and run. fread returned 1, and Mira is back with her 4200 points. Last night's score survived the restart.
Arrays of Records
Saving Three Players in One Call
A board has more than one hero. Keep the players in an array of structs: records back to back, in one block. Lesson 10.3 covers it fully. Because the block is one piece, one fwrite with a count of 3 saves all three players, and one fread loads them into a second array, back. To keep the demo short, this program skips the NULL checks. Real programs keep them. Then the proof. For each restored player, strcmp compares the name, and double equals compares the score. The loop runs to got, the number really read, not a typed 3. So a short file can never make it visit empty boxes. Build and run. Wrote 3, read 3, and every player matches. The file holds 60 bytes. Player number k starts at byte 20 times k, so fseek, from 9.8, could jump straight to any player.
Hidden Bytes
Padding Between a Char and an Int
Our struct Player was lucky: 16 plus 4 is exactly 20. Often the compiler adds invisible gaps, called padding. Here's a struct with a char, then an int. The members add up to 5 bytes. offsetof, from stddef.h, says where a member starts. Run it on this Mac. The struct takes 8 bytes, and n starts at byte 4. Three unused bytes sit after tag, so that the int starts at a multiple of 4, a spot the processor likes. The compiler chooses the gap. Another compiler, or another kind of machine, may choose differently.
Quick Check
A New Member Breaks the Old Loader
Quick check. Priya adds a tokens member to the save program, between name and score, and gives hero 12 tokens. She rebuilds the save program and runs it. The loader stays exactly as it was. What does the loader print now? Pause and predict. Build the new saver, run it, then run the old loader: Mira with 12 points. fread still returned 1. The file now holds 24 bytes, and tokens sits at bytes 16 to 19. The loader reads 20 bytes into its old blueprint, so it takes those 4 bytes as the score. The real 4200 is never read. And fread can't warn you: it read one item of 20 bytes, exactly as asked. A file of raw structs has no labels.
Limits
Why Struct Files Rarely Travel
That's the catch with struct files. The bytes depend on the program, the compiler and the machine. The size of an int, the byte order, and the padding can all differ. So can the members, as you just saw. A struct file works well when the same program, built the same way, reads it back, as in the arcade. To share data between different systems, write text with fprintf, from 9.7, or save each member in a format you define.
Key Takeaways
One Block Out, One Block Back
To sum up. A struct is one block, so one fwrite saves a whole record, and one fread restores it. Start with all zeros, and check every count the functions return. An array of structs saves and loads in a single call. And padding, byte order and layout tie the file to the program that wrote it.
Try It
Counting Records Without a Stored Count
Something to try. Without a stored count, how could a loader find out how many players team.bin holds? Hint: fseek to the end, ask ftell where you are, and divide by the size of one struct Player.
About Programming in C at UPI Study
Programming in C (Computer Science 240) is a self-paced online course of 78 video lessons in 11 chapters, from pseudocode and your first program to data types, decisions, loops, functions, arrays, strings, pointers, files, structures, dynamic memory and linked lists. It carries a NCCRS credit recommendation for 3 semester credits.
Every lesson transcript is free on pages like this one, and the videos are free with a free UPI Study account. Enrolling adds a practice quiz after each lesson, the graded work and final exam that earn the credit, lifetime access, and an official transcript on completion. UPI Study has helped over 130,000 students with college credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
Enroll now → Course details Download the syllabus All Computer Science courses Every course with PRO →
Compare: C vs C++
Why take it here
Why students take Programming in C with UPI Study
Where the credit goes
Universities that work with NCCRS
Programming in C carries a NCCRS credit recommendation. These universities work with NCCRS; some are UPI Study's signed partners. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
Thomas Edison State UniversitySigned partner
University of the PeopleSigned partner
Charter Oak State CollegeSigned partner
Strayer UniversitySigned partner
Columbia Southern UniversitySigned partner
Indiana TechSigned partner
Penn StateWorks with NCCRS
Southern New Hampshire UniversityWorks with NCCRS
SUNYWorks with NCCRS
+many more cooperating universitiesFind my college →Find my college → Not listed? Ask Athena in the corner of this page, or book a 15-minute call.
FAQ
Questions students ask us
About Workshop: Saving and Restoring Structures in Binary Files
How do you write a struct to a binary file in C?
Why should you zero a struct before saving it to a file?
Why does a struct with a char and an int take 8 bytes?
Can a binary file of structs be read on a different computer?
About the Programming in C course
How many college credits is Programming in C?
How much does Programming in C cost and what is included?
Which universities accept UPI Study credits?
How long does Programming in C take?
How are the exams done?
How do my credits reach my college?
Ready for the full course? Earn 3 credits in Programming in C.
78 video lessons, a quiz after each one, and the graded work that earns the credit. Recommended for credit by NCCRS.
3 credits · NCCRSEnroll →