Backend Systemsbeginner
C File I/O & the Standard Library
Read and write files in C using fopen, fread, fwrite, and fprintf. Explore the C standard library: string functions, math, time, and random numbers.
Asma HafeezApril 17, 20265 min read
cfile-iostdiostdlibstandard-library
C File I/O & the Standard Library
C's standard library provides functions for file I/O, string manipulation, math, and more — all via #include.
Opening and Closing Files
C
#include <stdio.h>
FILE* file = fopen("data.txt", "r"); // open for reading
if (file == NULL) {
perror("Failed to open file"); // prints error message
return 1;
}
// ... use the file ...
fclose(file); // always close when doneFile Modes
| Mode | Meaning |
|------|---------|
| "r" | Read (file must exist) |
| "w" | Write (creates or truncates) |
| "a" | Append (creates if needed) |
| "r+" | Read + write (file must exist) |
| "w+" | Read + write (creates or truncates) |
| "rb", "wb" | Binary mode versions |
Reading Text Files
C
#include <stdio.h>
// Read line by line
void read_lines(const char* path) {
FILE* f = fopen(path, "r");
if (!f) { perror(path); return; }
char line[256];
int line_num = 1;
while (fgets(line, sizeof(line), f) != NULL) {
// fgets keeps the newline — strip it
line[strcspn(line, "\n")] = '\0';
printf("%3d: %s\n", line_num++, line);
}
fclose(f);
}
// Read single characters
int count_chars(const char* path) {
FILE* f = fopen(path, "r");
if (!f) return -1;
int count = 0, ch;
while ((ch = fgetc(f)) != EOF) count++;
fclose(f);
return count;
}
// Read entire file into buffer
char* read_file(const char* path) {
FILE* f = fopen(path, "rb");
if (!f) return NULL;
fseek(f, 0, SEEK_END); // seek to end
long size = ftell(f); // get position = size
rewind(f); // back to beginning
char* buf = malloc(size + 1);
if (!buf) { fclose(f); return NULL; }
fread(buf, 1, size, f);
buf[size] = '\0'; // null-terminate
fclose(f);
return buf; // caller must free!
}Writing Text Files
C
// Write formatted text
void write_report(const char* path, int count, double avg) {
FILE* f = fopen(path, "w");
if (!f) { perror(path); return; }
fprintf(f, "=== Report ===\n");
fprintf(f, "Count: %d\n", count);
fprintf(f, "Average: %.2f\n", avg);
fclose(f);
}
// Append to log file
void log_message(const char* path, const char* msg) {
FILE* f = fopen(path, "a");
if (!f) return;
time_t now = time(NULL);
char timestamp[30];
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", localtime(&now));
fprintf(f, "[%s] %s\n", timestamp, msg);
fclose(f);
}Binary Files
C
typedef struct {
char name[50];
int age;
double gpa;
} Student;
// Write binary
void save_students(const char* path, Student* students, int n) {
FILE* f = fopen(path, "wb");
if (!f) return;
fwrite(&n, sizeof(int), 1, f); // write count
fwrite(students, sizeof(Student), n, f); // write all students
fclose(f);
}
// Read binary
Student* load_students(const char* path, int* out_count) {
FILE* f = fopen(path, "rb");
if (!f) return NULL;
int n;
fread(&n, sizeof(int), 1, f);
Student* students = malloc(n * sizeof(Student));
if (!students) { fclose(f); return NULL; }
fread(students, sizeof(Student), n, f);
fclose(f);
*out_count = n;
return students; // caller must free!
}String Functions (<string.h>)
C
#include <string.h>
char s1[] = "Hello, World!";
char s2[100];
strlen(s1); // 13 — length without null terminator
strcpy(s2, s1); // copy s1 into s2
strncpy(s2, s1, 5); // copy at most 5 chars (safer)
s2[5] = '\0'; // ensure null terminator
strcat(s2, " C!"); // append " C!" to s2
strncat(s2, s1, 3); // append at most 3 chars
strcmp("apple", "banana"); // negative (a < b)
strncmp("abc", "abd", 2); // 0 — first 2 chars equal
strstr(s1, "World"); // pointer to "World" in s1, or NULL
strchr(s1, 'W'); // pointer to first 'W', or NULL
strtok(s1, ","); // tokenize (modifies string!)
// Convert case (character by character)
#include <ctype.h>
char ch = 'a';
char upper = toupper(ch); // 'A'
int isalpha = isalpha(ch); // 1 (true)
int isdigit = isdigit('5'); // 1 (true)Math Functions (<math.h>)
C
#include <math.h>
// Link with: gcc ... -lm
double x = 2.0;
sqrt(x); // 1.414...
pow(x, 10); // 1024.0
fabs(-3.14); // 3.14 (absolute value)
floor(3.7); // 3.0
ceil(3.2); // 4.0
round(3.5); // 4.0
log(M_E); // 1.0 (natural log)
log10(100); // 2.0
sin(M_PI / 2); // 1.0
cos(0.0); // 1.0Random Numbers (<stdlib.h>)
C
#include <stdlib.h>
#include <time.h>
// Seed with current time for different results each run
srand((unsigned int)time(NULL));
// Random int in range [min, max]
int random_int(int min, int max) {
return min + rand() % (max - min + 1);
}
// Roll a die
int die = random_int(1, 6);
// Random double in [0, 1)
double random_double(void) {
return (double)rand() / ((double)RAND_MAX + 1.0);
}String Conversion (<stdlib.h>)
C
// String to number
int n = atoi("42"); // 42
double d = atof("3.14"); // 3.14
long l = strtol("100", NULL, 10); // 100 (base 10)
// Number to string
char buf[32];
sprintf(buf, "%d", 42); // "42"
snprintf(buf, sizeof(buf), "%.2f", 3.14159); // "3.14" (safer)Key Takeaways
- Always check
fopenreturn value — it returns NULL if the file can't be opened - Always
fclose— unclosed files may not flush their buffer - Use
fgetsinstead ofgets(buffer overflow) andsnprintfinstead ofsprintf - Binary I/O with
fread/fwriteis fast but platform-specific (endianness, struct padding) - Strip the newline from
fgetsresults:line[strcspn(line, "\n")] = '\0'
Enjoyed this article?
Explore the Backend Systems learning path for more.
Found this helpful?
Leave a comment
Have a question, correction, or just found this helpful? Leave a note below.