File

Dalam pemrograman dengan bahasa C atau C++, kita bisa menyimpan file dengan nama sesuai keinginan kita. Kita juga bisa membuka kembali isi file yang sudah kita simpan. Untuk menggunakan file, kita menggunakan perlu membuka filenya dengan fopen. Fungsi fopen digunakan dengan pola sebagai berikut ini.

  • fopen("nama_file", "r/w/a/rw/hak_akses_lainnya");

Function fopen membutuhkan variabel pointer dengan tipe data FILE sebagai handler dari file yang dibuka. Setelah handler dari file didapatkan, kita bisa membaca atau menulis file sesuai hak akses yang sudah kita pilih. Setelah kita selesai menulis atau membaca file, kita perlu menggunakan fclose() untuk menutup akses terhadap file yang sudah kita buka dengan fopen.

#include <stdio.h>

int main(){
FILE *fl;
    fl=fopen("file.txt", "w");
    //ubah dan simpan file di sini.
    fclose(fl);
    return 0;
}

Pada contoh di atas, kita membuka file bernama "file.txt" di "direktori / folder yang sedang aktif" saat file dibuat. Saat kita mengcompile dari IDE, direktori yang aktif adalah folder utama project kita. Jika kita menjalankan programnya secara langsung, maka direktori yang aktif adalah folder tempat program kita dijalankan.

Variabel fl digunakan sebagai file handler dan "w" sebagai hak akses. Argumen untuk parameter kedua berisi "w"(write) menunjukkan bahwa kita akan membuat file baru untuk "diisi" atau ditulis. Function yang bisa kita gunakan untuk file yang dibuka dengan hak akses "w" yaitu :

  • fprintf : Menuliskan beberapa isi variabel ke dalam file. Cara penggunaannya sama dengan printf.
  • fwrite : Menuliskan sekumpulan karakter atau string dengan batas ukuran tertentu.
  • fputc : Menuliskan satu karakter ke file.

Selain w, ada beberapa hak akses yang bisa kita gunakan untuk parameter kedua dari fopen.

  1. w => membuat file baru untuk ditulis
  2. r => membuka file untuk dibaca dan disalin isi datanya
  3. a => membuka file untuk ditambah isi datanya mulai dari akhir file
  4. w+ => membuat file baru untuk ditulis dan dibaca.
  5. r+ => membuka file yang sudah ada untuk dibaca dan ditimpa mulai dari awal file.
  6. a+ => membuka file yang sudah ada untuk dibaca dan ditimpa mulai dari akhir file.

Berikutnya, kita akan menyelipkan fprintf diantara fopen dan fclose.

#include <stdio.h>
#include <string.h>

int main(){
FILE *fl;
char s[]="coba cek isi filenya";
    fl=fopen("file.txt", "w");
    if(fl){
        fprintf(fl, "%s", s);
        fclose(fl);
    }else printf("file tidak bisa dibuat");
    return 0;
}

Function fopen akan mengembalikan null jika file tidak ada. Jika file sukses dibuka, variabel bisa digunakan sebagai file handler. Kalian perlu memastikan file sudah berhasil dibuka atau belum dengan if agar tidak muncul pesan error saat runtime.

Kita bisa "mencetak" output ke output standar seperti terminal atau console dengan printf. Kita juga bisa menggunakan cara yang sama untuk "mencetak" tulisan ke dalam file dengan fprintf. Hasil dari fprintf tidak ditampilkan di console atau terminal. Hasil dari program yang menggunakan printf bisa kalian di dalam folder dari projectnya.

Membaca File

Jika fprintf hampir sama dengan printf (walaupun target outputnya berbeda), maka fscanf adalah versi lain dari scanf dengan file sebagai targetnya. Untuk menggunakan fscanf, hak akses file harus diubah jadi r, rw, atau a.

Kita akan melihat isi file yang dihasilkan kode program sebelumnya (sebanyak satu baris) dengan fscanf. Hak akses yang akan kita gunakan adalah "r"(read). Kita tidak menggunakan "w" karena itu akan mengosongkan isi file untuk ditulis ulang.

#include <stdio.h>
#include <string.h>

int main(){
FILE *fl;
char s[100]="";
    fl=fopen("fileku.txt", "r");
    if(fl){
     	fscanf(fl, "%[^\n]s", s);
        printf("%s", s);
        fclose(fl);
    }
    return 0;
};

Contoh di atas menggunakan fscanf untuk membaca file perbaris. Hak aksesnya menggunakan "r", yang artinya file hanya bisa dibaca. Function fscanf dipakai dengan cara yang sama dengan scanf. Selain fscanf, kalian juga bisa memakai fgets untuk mendapakan hasil yang sama.

#include <stdio.h>
#include <string.h>

int main(){
FILE *fl;
char s[100]="";
    fl=fopen("fileku.txt", "r");
    if(fl){
     	fgets(s, 100, fl);
        printf("%s", s);
        fclose(fl);
    }
    return 0;
};

Function fgets membaca satu baris teks seperti scanf dengan "%[^n]". Tapi, ini lebih aman karena kalian bisa membatasi panjang karakter yang dibaca dengan argumen di parameter kedua fgets.

Membaca dan Menulis Isi File Per Karakter

Jika kita ingin membaca isi file perkarakter, kita bisa menggunakan fgetc. Selain fgetc, ada function fputc yang digunakan untuk menuliskan satu karakter ke dalam file.

#include <stdio.h>

int main(){
FILE *fl;
int c='A';
    fl=fopen("file.txt", "w");
    while(c<='Z'){
        fputc(c, fl);
        c++;
    }
    fclose(fl);

    fl=fopen("file.txt", "r");
    if(fl){
        while(1){
            c=fgetc(fl);
            if(!feof(fl))printf("%c", c);
            else break;
        }
        fclose(fl);
    }
    return 0;
}

Membaca File Binary

Kalau kalian membaca file yang berisi karakter selain huruf, kalian tidak bisa membacanya perbaris dengan fscanf maupun fgets. Tapi, kalian bisa membaca dan menulis isi filenya langsung menggunakan fwrite dan fread. 

Function fwrite dan fread sebaiknya dipakai untuk file binary, walaupun kalian juga bisa memakainya untuk teks biasa. Untuk membaca mode binary, tambahkan "b" ke hak akses filenya.

  • wb => membuat file baru untuk ditulis.
  • rb => membuka file untuk dibaca dan disalin isi datanya
  • ab => membuka file untuk ditambah isi datanya mulai dari akhir file
  • wb+ => membuat file baru untuk ditulis dan dibaca.
  • rb+ => membuka file yang sudah ada untuk dibaca dan ditimpa mulai dari awal file.
  • ab+ => membuka file yang sudah ada untuk dibaca dan ditimpa mulai dari akhir file.

Kalian perlu menentukan karakter maksimal yang akan dibaca dengan fwrite atau fread. Kalau kalian tidak yakin, kalian bisa pakai function fseek dan ftell untuk mengetahui ukuran file.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
int ukuran;
char nama_file[256]="fileku.txt";
char isi_file[100]="Isi file untuk tes.";
char *tmp;

  FILE *fl=fopen(nama_file, "wb");//buka file dengan mode binary

  if(fl){
      fwrite(isi_file, strlen(isi_file)+1, 1, fl);
      fclose(fl);
  }

  fl=fopen(nama_file, "rb");//buka file dengan mode binary
  //pastikan filenya ada
  if(fl){
     fseek(fl, 0, SEEK_END);//cari akhir file
 
     ukuran=ftell(fl);//hitung ukuran berdasarkan posisi pointer file
     printf("ukuran : %d\n", ukuran);
     tmp=(char*)malloc((ukuran+1)*sizeof(char));//alokasikan memori.
     rewind(fl);//balik ke awal file
 
     fread(tmp, ukuran, 1, fl);//simpan isi file ke memori yg dialokasikan untuk tmp sebelum diolah lagi seperti string.
     tmp[ukuran-1]=0;//Tambahkan 0 atau null ke akhir teks agar teks bisa dicetak.
 
     printf("Isi : %s\n", tmp);
     printf("Huruf pertama: %c\n", tmp[0]);
     free(tmp);
  }
  return 0;
}
Output :
ukuran : 20
Isi : coba cek isi filenya
Huruf pertama: c

Karena ukuran file tidak bisa dipastikan, kalian perlu pakai pointer dan alokasi memori. Saat mengalokasikan memori, kalian sebaiknya menambah ukurannya sebanyak satu byte.

Contoh di atas membaca satu file teks secara utuh. Kalau file yang dibaca bukan teks, kalian tidak bisa langsung mencetak isinya seperti string. Kalian perlu mengolah filenya perkarakter.