ITM102 Structured Programming in C

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 (fprintf writes to transactions.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() and circle() for pedestrian crossings.

4. Input Validation & Error Handling

Common Validation Techniques

  1. Range Checks: Ensure values are within limits (e.g., age 1–120).
  2. Format Checks: Verify input matches expected patterns (e.g., phone number 7xxxxxxxx).
  3. 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) or fflush(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 fflush to 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

  1. eSewa’s Transaction System

    • Uses fprintf to log payments in payments.dat (binary mode for speed).
    • Validates user IDs with strncmp before processing.
  2. Pathao’s Driver App

    • Draws real-time routes using line() and circle() for pickup/drop locations.
    • Flushes GPS data every 5 seconds (fflush) to update the map instantly.
  3. Nepal Rastra Bank’s ATM

    • Validates PINs with strcmp and logs failed attempts to security.log.
    • Uses fwrite to store transaction records in a binary file for audits.

Exam Tip

  1. 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.
  2. 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)) { ... }).
  3. Common Pitfalls:

    • Forgetting & in scanf (e.g., scanf("%d", age) → WRONG; must be scanf("%d", &age)).
    • Not flushing buffers in critical applications (e.g., logging systems).
    • Using gets() (unsafe; use fgets() instead).
  4. Graphics Trick:

    • Always initialize graphics with initgraph(&gd, &gm, "path") before drawing.
    • Use getmaxx()/getmaxy() to center shapes dynamically.

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…