Cara Membaca File Teks di Bahasa C dengan Fungsi fopen

Layar laptop menampilkan kode bahasa C untuk membaca file teks di meja kerja

Untuk membaca file teks di bahasa C, kamu memakai fopen dengan mode "r", lalu mengambil isinya memakai fgets, fscanf, atau fgetc, dan terakhir menutup file dengan fclose. Tiga langkah itu sudah cukup untuk file sederhana. Yang sering bikin bingung justru detail kecil: kapan pointer file bernilai NULL, bagaimana newline ikut terbaca, dan kenapa isi file kadang terpotong.

Bagian berikut membahas alur lengkap membaca file teks, mulai dari membuka file, memilih fungsi pembaca yang cocok, menangani error, sampai kebiasaan yang bikin kode aman dipakai ulang.

Membuka file dengan fopen

Semua operasi file di C dimulai dari FILE *, sebuah pointer yang mewakili koneksi antara program dan file di disk. Fungsi fopen mengembalikan pointer itu, atau NULL kalau file gagal dibuka.

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("catatan.txt", "r");

    if (fp == NULL) {
        printf("File tidak bisa dibuka.n");
        return 1;
    }

    printf("File berhasil dibuka.n");
    fclose(fp);
    return 0;
}

Mode "r" membuka file untuk dibaca. Kalau file tidak ada, fopen mengembalikan NULL tanpa menampilkan pesan apa pun. Pemeriksaan NULL bukan formalitas; tanpa itu, program akan mengakses alamat memori tak valid dan berhenti dengan crash.

Mode fopen dan bedanya

Ada beberapa mode teks yang sering dipakai:

  • "r" — baca file yang sudah ada. Gagal kalau file tidak ditemukan.
  • "w" — tulis file. Isi lama dihapus, file dibuat kalau belum ada.
  • "a" — tambah isi di akhir file tanpa menghapus data lama.
  • "r+" — baca dan tulis pada file yang sudah ada.

Untuk membaca teks, pakai "r". Mode "w" memakai kata yang sama dengan “write” dan memang menghapus isi file begitu dibuka, jadi jangan tertukar.

Mengambil isi file dengan fgets

fgets membaca sebaris teks sekaligus, sampai bertemu newline atau sampai batas buffer tercapai. Fungsi ini menerima tiga argumen: buffer tujuan, ukuran buffer, dan pointer file.

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("catatan.txt", "r");
    if (fp == NULL) {
        printf("File tidak bisa dibuka.n");
        return 1;
    }

    char baris[256];

    while (fgets(baris, sizeof(baris), fp) != NULL) {
        printf("%s", baris);
    }

    fclose(fp);
    return 0;
}

Perulangan while berhenti ketika fgets mengembalikan NULL, yang menandakan akhir file atau error. Pola ini adalah cara paling umum membaca file teks baris per baris di C.

Ukuran buffer menentukan berapa banyak karakter yang bisa dibaca dalam satu panggilan. Kalau file punya baris lebih panjang dari buffer, sisanya akan terbaca di panggilan berikutnya. Jadi tidak ada data yang hilang selama perulangan tetap berjalan.

Soal newline di akhir baris

fgets menyertakan karakter newline n ke dalam buffer kalau ada. Artinya, kalau kamu langsung membandingkan isi baris dengan string lain memakai strcmp, hasilnya bisa meleset karena ada n yang menempel.

#include <string.h>

baris[strcspn(baris, "n")] = '';

Baris di atas memotong newline dari string. strcspn mencari posisi karakter pertama yang ada di dalam set, lalu karakter itu diganti dengan terminator string. Cukup satu baris dan perbandingan jadi lebih mudah diprediksi.

fscanf dan fgetc untuk kebutuhan lain

fgets cocok untuk teks bebas, tapi tidak selalu jadi pilihan terbaik. Dua fungsi lain punya kegunaan masing-masing.

fscanf untuk data terstruktur

Kalau file berisi data dengan format tetap, misalnya angka dan nama yang dipisah spasi, fscanf lebih ringkas.

int nim;
char nama[64];

while (fscanf(fp, "%d %63s", &nim, nama) == 2) {
    printf("%d - %sn", nim, nama);
}

fscanf mengembalikan jumlah item yang berhasil dibaca. Memeriksa nilai kembalian sama dengan 2 memastikan kedua data terbaca utuh sebelum dipakai. Kalau format di file berubah, perulangan berhenti tanpa mengolah data setengah jadi.

Keterbatasan fscanf: ia berhenti membaca string saat menemukan spasi. Nama dengan dua kata akan terpotong. Untuk kasus itu, fgets tetap lebih aman.

fgetc untuk membaca per karakter

fgetc mengambil satu karakter dari file tiap kali dipanggil. Hasilnya bisa disimpan di variabel int, bukan char, karena nilai EOF berada di luar jangkauan char.

int c;
while ((c = fgetc(fp)) != EOF) {
    putchar(c);
}

Pola ini berguna saat kamu perlu memproses teks karakter demi karakter, misalnya menghitung kata atau mencari pola tertentu. Ukuran buffer tidak jadi masalah karena karakter diambil satu per satu.

Penanganan error yang tidak boleh dilewat

Ada tiga jenis masalah yang muncul saat membaca file, dan masing-masing butuh penanganan berbeda.

  1. File tidak ditemukan atau tidak bisa diakses. fopen mengembalikan NULL. Periksa nilainya sebelum memakai pointer.
  2. Gagal membaca di tengah jalan. Setelah perulangan selesai, panggil feof dan ferror untuk membedakan apakah perulangan berhenti karena akhir file atau karena error.
  3. File lupa ditutup. Setiap fopen yang berhasil harus diimbangi fclose. Pointer file adalah sumber daya terbatas, dan menumpuknya bisa membuat program menabrak batas sistem.
if (ferror(fp)) {
    printf("Terjadi error saat membaca file.n");
}
fclose(fp);

Pemeriksaan ini membedakan akhir file yang normal dari kegagalan baca yang tidak terlihat. Banyak program kecil melewatkannya, dan akibatnya bug muncul hanya pada kondisi tertentu.

Kalau kode pengelolaan pointer-nya masih terasa membingungkan, ada baiknya berhenti sebentar dan membaca cara menggunakan pointer pada bahasa C untuk pemula, karena FILE * sendiri adalah penerapan pointer yang langsung terasa manfaatnya.

Contoh program lengkap

Berikut program yang membaca file, menampilkan setiap baris dengan nomor, dan menutup file dengan benar.

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("catatan.txt", "r");
    if (fp == NULL) {
        printf("File catatan.txt tidak ditemukan.n");
        return 1;
    }

    char baris[256];
    int nomor = 1;

    while (fgets(baris, sizeof(baris), fp) != NULL) {
        printf("%3d | %s", nomor, baris);
        nomor++;
    }

    if (ferror(fp)) {
        printf("Gagal membaca sebagian isi file.n");
    }

    fclose(fp);
    return 0;
}

Kompilasi dengan gcc baca_file.c -o baca_file, lalu jalankan di folder yang sama dengan catatan.txt. Kalau file berada di folder lain, tulis path relatif atau absolut dengan tepat. Di Windows, path seperti "C:\data\catatan.txt" memerlukan garis miring ganda karena backslash adalah karakter escape.

Kebiasaan yang bikin kode file lebih aman

  • Selalu periksa hasil fopen sebelum dipakai.
  • Pakai sizeof(buffer) sebagai argumen kedua fgets, bukan angka yang ditulis ulang, supaya ukuran tidak pernah tidak sinkron.
  • Potong newline dengan strcspn kalau isi baris akan dibandingkan atau diolah lebih lanjut.
  • Panggil fclose di semua jalur keluar program, termasuk saat ada error di tengah.
  • Biasakan menulis kode yang memisahkan pembukaan, pembacaan, dan penutupan file agar mudah ditelusuri saat ada masalah.

Membaca file teks di C pada dasarnya adalah urutan yang tetap: buka, baca, tutup. Setelah tiga langkah itu terbiasa, kamu bisa menangani file yang lebih besar, memproses data baris demi baris, atau menggabungkan pembacaan file dengan struktur data seperti array dan linked list.

Pertanyaan yang Sering Diajukan

Apa bedanya fgets dan fscanf saat membaca file?

fgets membaca sebaris penuh sampai newline, jadi cocok untuk teks bebas yang mengandung spasi. fscanf membaca berdasarkan format dan berhenti saat menemukan spasi, sehingga lebih pas untuk data terstruktur seperti angka dan kata tunggal.

Kenapa fopen mengembalikan NULL padahal file ada?

Penyebab yang paling sering adalah path salah, program dijalankan dari folder berbeda, atau file sedang dipakai proses lain sehingga tidak bisa diakses. Cek juga hak akses file dan pastikan nama file sama persis, termasuk huruf besar-kecil, karena sistem berbasis Unix membedakan keduanya.

Apakah file harus selalu ditutup dengan fclose?

Ya. fclose menulis sisa data yang masih tertahan di buffer dan melepaskan sumber daya yang dipakai file. Kalau file tidak ditutup, data bisa tidak tersimpan sepenuhnya, terutama setelah operasi tulis, dan jumlah file yang bisa dibuka dalam satu waktu terbatas.