C Program to reverse the first n characters in a file.

This program reads a filename and a count n from the command line, reads the first n characters from the file, reverses them in-place using a two-pointer swap, and prints the result. It demonstrates combining command-line argument parsing, file I/O with fread(), and in-place string reversal in a single practical program.

The original post used conio.h, process.h, void main(), and a one-character-only hack (*argv[2]-48) that silently broke for any n >= 10. This rewrite uses atoi(), proper file I/O, fprintf(stderr, ...) for errors, and a clean two-pointer reversal.

C Program: Reverse First n Characters in a File

/* Reverse first n characters in a file (command-line arguments)
 * Usage: ./reversefile <filename> <n>
 * Compile: gcc -ansi -Wall -Wextra reversefile.c -o reversefile */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    FILE *fp;
    char buf[256];
    int n, i, j, len;
    char tmp;

    if (argc != 3) {
        fprintf(stderr, "Usage: %s <filename> <n>\n", argv[0]);
        return 1;
    }

    n = atoi(argv[2]);
    if (n <= 0) {
        fprintf(stderr, "Error: n must be a positive integer\n");
        return 1;
    }
    if (n > (int)(sizeof(buf) - 1)) {
        fprintf(stderr, "Error: n too large (max %d)\n", (int)(sizeof(buf) - 1));
        return 1;
    }

    fp = fopen(argv[1], "r");
    if (fp == NULL) {
        fprintf(stderr, "Error: cannot open '%s'\n", argv[1]);
        return 1;
    }

    len = (int)fread(buf, 1, (size_t)n, fp);
    fclose(fp);

    if (len == 0) {
        fprintf(stderr, "Error: file is empty or n exceeds file length\n");
        return 1;
    }
    buf[len] = '\0';

    /* Reverse in-place using two-pointer swap */
    i = 0;
    j = len - 1;
    while (i < j) {
        tmp = buf[i];
        buf[i] = buf[j];
        buf[j] = tmp;
        i++;
        j--;
    }

    printf("First %d characters reversed: %s\n", len, buf);
    return 0;
}

How to Compile and Run

gcc -ansi -Wall -Wextra reversefile.c -o reversefile

# Create a test file
echo "Hello, World!" > testfile.txt

# Reverse first 5 characters
./reversefile testfile.txt 5

# Reverse first 13 characters
./reversefile testfile.txt 13

Sample Output

First 5 characters reversed: olleH
First 13 characters reversed: !dlroW ,olleH

How It Works — Step by Step

Step Action Result (n=5, file=”Hello, World!”)
1 Validate argc == 3 argv[1]=”testfile.txt”, argv[2]=”5″
2 n = atoi(argv[2]) n = 5
3 fopen(argv[1], “r”) File opened for reading
4 fread(buf, 1, 5, fp) buf = “Hello”, len = 5
5 buf[5] = ‘\0’ null-terminate the buffer
6 Two-pointer swap: i=0,j=4 → swap H and o buf = “oellH”
7 i=1, j=3 → swap e and l buf = “olleH”
8 i=2, j=2 → i < j is false, stop buf = “olleH” (middle char unchanged)
9 printf result “First 5 characters reversed: olleH”

Code Explanation

  • atoi(argv[2]) instead of *argv[2]-48 — the original used *argv[2]-48 which dereferences argv[2] to get the first character and subtracts ASCII ‘0’ (decimal 48) to get a digit. This only works for single digits (n = 0–9). For n=10 or above it silently produces wrong results. atoi() converts the entire string to an integer and handles any number of digits.
  • fread(buf, 1, n, fp) — reads up to n bytes (one byte per read element) into buf. Returns the actual number of bytes read (may be less than n if the file is shorter). The return value is stored in len, not n, so the reversal always operates on exactly the bytes that were read.
  • buf[len] = '\0' — fread does not null-terminate the buffer. Null termination is required before passing to printf with %s. Without it, printf reads past the valid data into garbage memory.
  • Two-pointer reversal — start i at the left end, j at the right end. Swap buf[i] and buf[j], then move i right and j left. Stop when i >= j. This runs in O(n/2) = O(n) time and O(1) extra space (just the tmp variable).
  • fclose(fp) before the reversal — close the file immediately after reading is done. There is no reason to keep it open while we reverse and print, and forgetting to close files is a resource leak.
  • Error messages to stderrfprintf(stderr, "...") writes error messages to the standard error stream. This keeps error output separate from normal output, which is important when the program is used in a pipeline.

What This Program Teaches

  • fread() for binary-safe reading — unlike fgets(), fread() reads raw bytes without interpreting newlines. It is the right choice when you want to read exactly n bytes from a file, regardless of content.
  • Two-pointer in-place reversal — this is a classic technique: no second array needed, just swap from both ends toward the middle in O(n) time. It is the same algorithm used to reverse arrays, strings, and linked lists.
  • Command-line arguments for file tools — any tool that processes files should take the filename as a command-line argument (not prompt the user). This makes the program scriptable — you can call it in a shell loop, pipe its output, or use it in a Makefile.
  • Validate before using argc/argv — always check that argc has the expected count before accessing argv[1], argv[2], etc. If the user omits an argument, argv[1] might be NULL and dereferencing it is undefined behavior.

Related Programs

Recommended book:
The C Programming Language — Kernighan & Ritchie (India) |
(US)
 | 
C Programming: A Modern Approach — K.N. King (India) |
(US)

Practice what you learned: C Aptitude Questions — or try our C Programming Quiz App on Android.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>