← Back to C Course | Chapter 10: File I/O | Lesson 3 of 6

C fread() & fwrite()

fread and fwrite move blocks of raw data to and from a file, like carrying whole boxes rather than single items. They are handy for saving structures.
Syntax
c
fwrite(&data, sizeof(data_type), count, file_pointer);

fread(&data, sizeof(data_type), count, file_pointer);

Writing binary blocks with fwrite()

Because it writes raw bytes rather than formatted text, fwrite() preserves the exact binary representation of data like floats or structs, unlike fprintf() which converts everything to human-readable text first.

Example: Writing binary blocks with fwrite()

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
	int numbers[3] = {1, 2, 3};
	FILE *fp = fopen("data.bin", "wb");
	fwrite(numbers, sizeof(int), 3, fp);
	fclose(fp);
	// Print formatted text to the screen
	printf("Wrote raw binary data");
	// Return 0 to signal that the program finished successfully
	return 0;
}

Reading binary blocks with fread()

If fread() returns fewer elements than you requested, it usually means you've hit the end of the file partway through -- always check this return value rather than assuming the full requested amount was read successfully.

Example: Reading binary blocks with fread()

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
	int numbers[3] = {1, 2, 3};
	FILE *fp = fopen("data.bin", "wb");
	fwrite(numbers, sizeof(int), 3, fp);
	fclose(fp);
	int result[3];
	fp = fopen("data.bin", "rb");
	fread(result, sizeof(int), 3, fp);
	fclose(fp);
	// Print formatted text to the screen
	printf("%d", result[1]);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Writing structures to files

This is far more efficient than writing each member of a structure individually with separate fprintf() calls, since fwrite() copies the structure's raw memory layout to disk in a single operation.

Example: Writing structures to files

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Define a structure type named Point
struct Point { int x, y; };
// Program execution starts in main()
int main() {
	struct Point p = {3, 4};
	FILE *fp = fopen("point.bin", "wb");
	fwrite(&p, sizeof(struct Point), 1, fp);
	fclose(fp);
	// Print formatted text to the screen
	printf("Struct written in one operation");
	// Return 0 to signal that the program finished successfully
	return 0;
}

Reading structures from files

This only works reliably if the reading program uses the exact same structure definition (including compiler, platform, and padding/alignment) as the program that wrote the file -- binary file formats are not portable across different compilers or architectures without extra care.

Example: Reading structures from files

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Define a structure type named Point
struct Point { int x, y; };
// Program execution starts in main()
int main() {
	struct Point p = {3, 4};
	FILE *fp = fopen("point.bin", "wb");
	fwrite(&p, sizeof(struct Point), 1, fp);
	fclose(fp);
	struct Point result;
	fp = fopen("point.bin", "rb");
	fread(&result, sizeof(struct Point), 1, fp);
	fclose(fp);
	// Print formatted text to the screen
	printf("%d %d", result.x, result.y);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Verifying read/write count

Comparing the returned count against your expected count is the only reliable way to detect a partial or failed read/write, since these functions don't otherwise raise an error the way some other I/O functions do.

Example: Verifying read/write count

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
	int numbers[3] = {1, 2, 3};
	FILE *fp = fopen("data.bin", "wb");
	size_t written = fwrite(numbers, sizeof(int), 3, fp);
	fclose(fp);
	// Print formatted text to the screen
	printf("%zu", written);
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Opening a binary file without the b in the mode, so text-mode translation can corrupt data on some systems.
  2. Writing structs that contain pointers, which stores addresses rather than the actual data.
  3. Reading a different number of bytes or items than were written.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.