What Is a Library Function, Really?
A library function is code someone else already wrote, tested, and compiled โ so you don't have to. printf(), scanf(), strlen() โ none of these are "built into" the C language itself; they're ordinary C functions living in a separately compiled library that ships with your compiler.
Here's the part that surprises people: #include <stdio.h> does not paste in printf's actual code. A header file only contains declarations โ a promise of the function's name, parameters, and return type. The real compiled implementation lives elsewhere, and gets attached to your program in a separate step called linking.
From source code to running program โ 4 stages
#include <stdio.h>, the compiler doesn't know printf's signature and may guess wrong about its parameters โ that's what a "implicit declaration of function" warning means. The header is just the promise; the linker keeps it.The stdio.h Function Family
stdio.h is the header you've used in every single program so far. It groups functions into a few clear jobs: console I/O, character I/O, file I/O, and string-based formatting.
| Function | Category | What it does |
|---|---|---|
| printf() / scanf() | Console I/O | Formatted output/input to the screen & keyboard |
| getchar() / putchar() | Character I/O | Read/write exactly one character |
| gets() / puts() | String I/O | Read/write a whole line (gets is unsafe โ see Strings lesson) |
| fopen() / fclose() | File handling | Open and close a file, returning a FILE* handle |
| fprintf() / fscanf() | File I/O | Formatted read/write directly to a file |
| fgets() / fputs() | File I/O | Line-based read/write to a file (or stdin) |
| fread() / fwrite() | Binary File I/O | Raw block read/write, for non-text data |
| sprintf() / sscanf() | String formatting | Format into / parse from a string instead of a file |
| feof() / ferror() | File status | Check if a file has ended, or if an error occurred |
| fflush() | Buffer control | Force any buffered output to be written immediately |
Character I/O: getchar() and putchar()
getchar() reads exactly one character from the keyboard; putchar() writes exactly one character to the screen. Every other input/output function in stdio.h is really built on this idea, just operating on more characters at once.
#include <stdio.h> int main() { char ch; printf("Type a character: "); ch = getchar(); // reads just ONE character printf("You typed: "); putchar(ch); // writes just ONE character putchar('\n'); // Read and echo characters one at a time until Enter printf("Type a word, then Enter: "); int c; while ((c = getchar()) != '\n') { putchar(toupper(c)); } putchar('\n'); return 0; }
Type a character: X You typed: X Type a word, then Enter: hello HELLO
EOF (end of input). Storing the result in a plain char can cause EOF detection to fail on some systems.Formatted File I/O: fprintf() and fscanf()
fprintf() and fscanf() work exactly like printf() and scanf(), except the first argument is a FILE* telling them where to read/write instead of the console. This is the same file-handling pattern used across the Hotel, Library, and Hospital projects.
#include <stdio.h> int main() { // --- Writing to a file --- FILE *fp = fopen("scores.txt", "w"); if (fp == NULL) { printf("Could not open file.\n"); return 1; } fprintf(fp, "%s %d\n", "Asha", 92); fprintf(fp, "%s %d\n", "Ravi", 78); fclose(fp); // --- Reading it back --- fp = fopen("scores.txt", "r"); char name[20]; int score; printf("Reading scores.txt:\n"); while (fscanf(fp, "%s %d", name, &score) == 2) { printf("%s scored %d\n", name, score); } fclose(fp); return 0; }
Reading scores.txt: Asha scored 92 Ravi scored 78
while (fscanf(...) == 2) is the standard way to read "until the file runs out of well-formed data" โ it stops the moment a read fails or reaches end-of-file.sprintf() and sscanf() โ Formatting Without a File
Sometimes you want printf's formatting power, but the destination should be a char array, not the screen. sprintf() does exactly that โ and sscanf() is its reverse, pulling values back out of a formatted string.
#include <stdio.h> int main() { char buffer[50]; int day = 5, month = 7, year = 2026; // build a formatted string in memory, just like printf but into buffer sprintf(buffer, "%02d/%02d/%d", day, month, year); printf("Formatted date: %s\n", buffer); // now parse values back OUT of a string, like scanf but from a variable int d, m, y; sscanf(buffer, "%d/%d/%d", &d, &m, &y); printf("Parsed back -> day=%d month=%d year=%d\n", d, m, y); return 0; }
Formatted date: 05/07/2026 Parsed back -> day=5 month=7 year=2026
sprintf(filename, "report_%d.txt", id);, or splitting a CSV line's fields with sscanf โ both patterns you'll see again in file-based projects.Beyond stdio.h โ The Rest of the Standard Library
stdio.h handles input/output, but C ships several other headers, each specializing in one kind of job. You've already used some of these in earlier lessons without necessarily naming them.
| Header | Purpose | Example functions |
|---|---|---|
| string.h | String manipulation | strlen, strcpy, strcat, strcmp, strstr |
| ctype.h | Character testing/conversion | toupper, tolower, isdigit, isalpha, isspace |
| math.h | Mathematical functions | sqrt, pow, ceil, floor, fabs |
| stdlib.h | General utilities | malloc, free, atoi, rand, srand, exit |
| time.h | Date & time | time, clock, difftime |
#include <stdio.h> #include <string.h> #include <math.h> #include <ctype.h> #include <stdlib.h> int main() { char word[] = "Recursion"; printf("string.h -> strlen(\"%s\") = %zu\n", word, strlen(word)); printf("ctype.h -> isalpha('7') = %d\n", isalpha('7')); printf("math.h -> sqrt(49) = %.1f\n", sqrt(49)); printf("stdlib.h -> atoi(\"42\") = %d\n", atoi("42")); return 0; }
string.h -> strlen("Recursion") = 9
ctype.h -> isalpha('7') = 0
math.h -> sqrt(49) = 7.0
stdlib.h -> atoi("42") = 42
-lm (e.g. gcc file.c -o file -lm), because the math library isn't linked in automatically like stdio.h's implementation usually is. This is the "linking" step from the concept diagram made concrete.Quick Quiz
What does #include <stdio.h> actually insert into your code?
Which compilation stage actually attaches printf's real implementation to your program?
Why does getchar() return an int instead of a char?
What is sprintf() used for?
Which header provides sqrt() and pow()?
Lesson Checklist
- I understand a header file only declares functions, it doesn't define them
- I can name the 4 stages: preprocess, compile, link, run
- I know the f-prefix naming pattern (fprintf, fscanf, fgets, fputs)
- I can use getchar()/putchar() for single-character I/O
- I can read and write formatted data to a file with fprintf/fscanf
- I understand sprintf()/sscanf() format into/parse from a string, not a file
- I can name at least 3 other standard headers and one function from each
- I completed the quiz