Structured Programming in CUnit 89 min read
I/O Functions in C: Formatting, Files & Graphics
Unit 8 of Structured Programming in C covers formatted vs. unformatted I/O, file handling, graphics programming, and input validation—essential for building interactive programs, processing data, and creating visual outputs in C.
TAKEAWAYS:
- Formatted I/O (
printf,scanf) uses format specifiers (%d,%f) for precise data handling, while unformatted I/O (getchar,putchar) processes raw bytes. - File operations (
fopen,fclose,fprintf) enable persistent data storage (e.g., saving user records in a bank system). - Graphics functions (
circle,line) draw shapes on the screen using the Graphics Interface Library (GIL). - Input validation ensures robust programs (e.g., rejecting invalid phone numbers in eSewa).
- Error handling (
ferror,feof) detects file/stream issues (e.g., corrupted transaction logs in Daraz). - Buffering (
fflush) controls output timing (critical for real-time systems like NTC’s traffic monitoring).
1. Formatted vs. Unformatted I/O
Definitions & Key Differences
| Feature | Formatted I/O (printf, scanf) |
Unformatted I/O (getchar, putchar) |
|---|---|---|
| Data Type Handling | Converts data types (e.g., %d for int) |
Treats data as raw bytes (characters) |
| Format Specifiers | Uses %d, %f, %s, etc. |
No specifiers; reads/writes one byte at a time |
| Efficiency | Slower (parsing overhead) | Faster (direct byte access) |
| Use Case | Structured data input/output | Low-level I/O (e.g., reading a file byte-by-byte) |
Example: Formatted I/O
#include <stdio.h>
int main() {
int age;
float salary;
printf("Enter age and salary: ");
scanf("%d %f", &age, &salary); // Reads 23 and 50000.50 as separate values
printf("Age: %d, Salary: %.2f", age, salary);
return 0;
}
Trace:
| Step | age |
salary |
Input Buffer | Output |
|---|---|---|---|---|
| 1 | - | - | "23 50000.50" | "Enter age and salary: " |
| 2 | 23 | - | "50000.50" | (user enters 23 50000.50) |
| 3 | 23 | 50000.50 | "" | "Age: 23, Salary: 50000.50" |
Example: Unformatted I/O
#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
ch = getchar(); // Reads 'A' as ASCII 65
putchar(ch); // Outputs 'A'
return 0;
}
Trace:
| Step | ch |
Input Buffer | Output |
|---|---|---|---|
| 1 | - | "" | "Enter a character: " |
| 2 | 65 | "A" | (user presses 'A' + Enter) |
| 3 | 65 | "\n" | "A" |
2. File Handling in C
Key Functions
| Function | Purpose | Example |
|---|---|---|
fopen() |
Opens a file (returns FILE* pointer) |
fp = fopen("data.txt", "r"); |
fclose() |
Closes a file | fclose(fp); |
fprintf() |
Writes formatted data to a file | fprintf(fp, "%d", age); |
fscanf() |
Reads formatted data from a file | fscanf(fp, "%f", &salary); |
fgets() |
Reads a line from a file | fgets(buffer, 100, fp); |
feof() |
Checks for end-of-file | while (!feof(fp)) { ... } |
Example: Saving Student Records (Like TU’s Exam Database)
#include <stdio.h>
struct Student {
int roll;
char name[50];
float marks;
};
int main() {
FILE *fp = fopen("students.dat", "wb"); // Binary write mode
struct Student s1 = {101, "Ramesh", 85.5};
fwrite(&s1, sizeof(struct Student), 1, fp);
fclose(fp);
return 0;
}
State After fwrite:
graph LR
A["File: students.dat (Binary)"] -->|"After fwrite"| B["Bytes: 0x65 0x00 0x01 0x64 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x40 0x49 0x00 0x00 0x00 0x00 0x00 0x00"]Real-World Tie-In:
- eSewa uses file handling to store transaction records (
fprintfwrites totransactions.log). - Nepal Rastra Bank logs all ATM transactions in binary files for auditing.
3. Graphics Programming in C
Key Functions (Graphics Interface Library - GIL)
| Function | Purpose | Example |
|---|---|---|
initgraph() |
Initializes graphics mode | initgraph(&gd, &gm, "C:\\TURBOC3\\BGI"); |
circle() |
Draws a circle | circle(200, 200, 100); |
line() |
Draws a line | line(100, 100, 300, 300); |
rectangle() |
Draws a rectangle | rectangle(50, 50, 250, 250); |
setcolor() |
Sets drawing color | setcolor(RED); |
getmaxx() |
Returns screen width | int width = getmaxx(); |
Example: Drawing a Traffic Signal (Like NTC’s Road Signs)
#include <graphics.h>
int main() {
int gd = DETECT, gm;
initgraph(&gd, &gm, "C:\\TURBOC3\\BGI");
// Draw red rectangle (signal body)
rectangle(100, 100, 200, 300);
// Draw red circle (STOP light)
setfillstyle(SOLID_FILL, RED);
floodfill(150, 150, WHITE);
getch();
closegraph();
return 0;
}
State After floodfill:
graph TD
A["Screen (640x480)"] --> B["Rectangle: (100,100)-(200,300)"] --> C["Filled Circle: (150,150) radius 50, RED"]Real-World Tie-In:
- Pathao’s Driver App uses graphics to display real-time routes (lines and polygons for roads).
- NTC’s Traffic Management System simulates signal timings with
delay()andcircle()for pedestrian crossings.
4. Input Validation & Error Handling
Common Validation Techniques
- Range Checks: Ensure values are within limits (e.g., age 1–120).
- Format Checks: Verify input matches expected patterns (e.g., phone number
7xxxxxxxx). - Error Handling: Use
ferror()to detect file read/write errors.
Example: Validating a Phone Number (Like Ncell’s Input)
#include <stdio.h>
#include <stdbool.h>
bool isValidPhone(char *phone) {
if (strlen(phone) != 10 || phone[0] != '7') return false;
for (int i = 0; i < 10; i++) {
if (!isdigit(phone[i])) return false;
}
return true;
}
int main() {
char phone[11];
printf("Enter 10-digit phone number: ");
scanf("%s", phone);
if (isValidPhone(phone)) {
printf("Valid Ncell number: %s\n", phone);
} else {
printf("Invalid! Must start with 7 and be 10 digits.\n");
}
return 0;
}
Trace for Invalid Input ("1234567890"):
| Step | phone |
isValidPhone |
Output |
|---|---|---|---|
| 1 | "1234567890" | false (starts with 1) | "Invalid! Must start with 7..." |
Real-World Tie-In:
- Khalti validates card numbers using Luhn’s algorithm (checksum validation).
- Daraz checks order IDs against a database before processing payments.
5. Buffering and Flushing
How Buffering Works
- Output Buffering: Data is stored in memory and written to a file/console in chunks (faster but may lose data on crash).
- Flushing: Forces immediate write using
fflush(stdout)orfflush(fp).
Example: Logging Transactions (Like NEPSE’s Stock Data)
#include <stdio.h>
int main() {
FILE *fp = fopen("transactions.log", "a");
fprintf(fp, "User 101 bought 50 shares at 1000 NPR\n");
fflush(fp); // Ensures data is written immediately
fclose(fp);
return 0;
}
State Before/After fflush:
graph LR
A["Before fflush"] -->|"Buffer"| B["Memory Buffer: 'User 101 bought...'"]
C["After fflush"] -->|"File"| D["transactions.log: 'User 101 bought...'"]Real-World Tie-In:
- Banks use
fflushto log ATM transactions instantly (prevents data loss during power cuts). - NTC’s Traffic Cameras flush buffers every second to avoid losing footage.
In the Real World
eSewa’s Transaction System
- Uses
fprintfto log payments inpayments.dat(binary mode for speed). - Validates user IDs with
strncmpbefore processing.
- Uses
Pathao’s Driver App
- Draws real-time routes using
line()andcircle()for pickup/drop locations. - Flushes GPS data every 5 seconds (
fflush) to update the map instantly.
- Draws real-time routes using
Nepal Rastra Bank’s ATM
- Validates PINs with
strcmpand logs failed attempts tosecurity.log. - Uses
fwriteto store transaction records in a binary file for audits.
- Validates PINs with
Exam Tip
For Short Questions:
- Formatted vs. Unformatted I/O: List 3 differences (e.g., "uses specifiers vs. raw bytes").
- Graphics Functions: Name 2 functions (
circle,line) and their parameters.
For Programming Questions:
- File Handling: Always include:
FILE *fp = fopen(...);- Error check (
if (fp == NULL) { ... }) fclose(fp)at the end.
- Input Validation: Use loops to re-prompt on invalid input (e.g.,
while (!isValidPhone(phone)) { ... }).
- File Handling: Always include:
Common Pitfalls:
- Forgetting
&inscanf(e.g.,scanf("%d", age)→ WRONG; must bescanf("%d", &age)). - Not flushing buffers in critical applications (e.g., logging systems).
- Using
gets()(unsafe; usefgets()instead).
- Forgetting
Graphics Trick:
- Always initialize graphics with
initgraph(&gd, &gm, "path")before drawing. - Use
getmaxx()/getmaxy()to center shapes dynamically.
- Always initialize graphics with
Practice Question:
Write a program to read a text file (data.txt) containing student names and marks, then display the highest scorer using fscanf and fgets. Validate that marks are between 0–100.
(Hint: Use fscanf(fp, "%s %f", name, &marks); and check marks >= 0 && marks <= 100.)
Based on the TU BITM syllabus for Structured Programming in C (ITM102), unit 8.
Discussion
Loading…