Analisis yang tuntas di workspace belum berarti tuntas: hasilnya harus keluar sebagai laporan yang dibaca manusia, atau sebagai data yang dimuat ulang besok dan dikonsumsi program lain. Menulis berkas adalah cermin dari membaca — dan pilihan formatnya menentukan siapa yang bisa membacanya. Chapter ini membahas sisi tulis:

  • Menulis teks terformat dengan fprintf (%d, %s, %.2f) lengkap dengan header kolom
  • Perilaku mode 'w' (menimpa) vs 'a' (append)
  • dlmwrite dengan delimiter dan presisi, plus writematrix/writetable untuk MATLAB modern
  • Menyimpan workspace ke .mat dengan save beserta versi -v7 dan -v7.3
  • Newline Windows vs Unix dan tabel pemilihan format keluaran

Aturannya: fprintf yang kita pakai ke Command Window bekerja juga ke berkas — cukup sertakan file identifier sebagai argumen pertama. Mekanismenya: format specifier %d (bilangan bulat), %s (teks), %.2f (pecahan dua desimal) mengendalikan bentuk tiap nilai, sementara lebar kolom seperti %-6s dan %6.2f meratakan kolom — tanda minus berarti rata kiri:

matlab
id    = [1; 2; 3];
nama  = {'Budi'; 'Siti'; 'Ani'};
nilai = [87.5; 92.3; 78.9];

fid = fopen('laporan.txt', 'w');
fprintf(fid, '%-4s %-6s %6s\n', 'id', 'nama', 'nilai');
for k = 1:numel(id)
  fprintf(fid, '%-4d %-6s %6.2f\n', id(k), nama{k}, nilai(k));
end
fclose(fid);
fprintf('%s', fileread('laporan.txt'));

Output yang Dihasilkan:

text
id   nama    nilai
1    Budi    87.50
2    Siti    92.30
3    Ani     78.90

Mari kita bedah baris-baris kode di atas:

  1. Baris 6 (fprintf(fid, ...)): identifier mengalihkan keluaran dari layar ke berkas laporan.txt; format specifier-nya persis sama dengan versi Command Window.
  2. Baris 7-9 (%-4d %-6s %6.2f): tiap kolom diberi lebar tetap — id rata kiri selebar 4, nama rata kiri selebar 6, nilai rata kanan selebar 6 — sehingga kolom lurus walau panjang isinya berbeda.
  3. Baris 11 (fprintf('%s', fileread(...))): fileread mengambil kembali seluruh isi berkas sebagai char, lalu fprintf menampilkannya — cara tercepat memverifikasi hasil tulisan.

Mode ‘w’ vs ‘a’: Menimpa atau Menambah #

Masalah nyatanya: script yang dijalankan ulang biasanya menimpa laporan lama — kadang itu diinginkan, kadang justru bencana. Mekanismenya: mode 'w' memotong berkas menjadi kosong sebelum menulis, sedangkan mode 'a' memindahkan posisi tulis ke akhir berkas sehingga baris baru menempel setelah baris lama:

matlab
fid = fopen('laporan.txt', 'a');
fprintf(fid, '%-4d %-6s %6.2f\n', 4, 'Dewi', 81.4);
fclose(fid);
isi = fileread('laporan.txt');
barisSemua = strsplit(isi, '\n');
if isempty(barisSemua{end})          % newline terakhir membuang elemen kosong
  barisSemua(end) = [];
end
fprintf('setelah append: %d baris (1 header + 4 data)\n', numel(barisSemua));

Output yang Dihasilkan:

text
setelah append: 5 baris (1 header + 4 data)

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (fopen(..., 'a')): tiga baris hasil fprintf mode 'w' tetap utuh; baris Dewi menjadi baris keempat.
  2. Baris 4-8 (fileread + strsplit): isi berkas dihitung ulang untuk membuktikan bahwa append benar-benar menambah, bukan mengganti; guard isempty membuang elemen kosong buangan newline terakhir.

dlmwrite, writematrix, dan writetable #

Untuk tabel numerik, dlmwrite menawarkan kendali dua hal sekaligus: delimiter dan presisi. Mekanismenya: name-value pair 'delimiter' menentukan pemisah kolom dan 'precision' menentukan format penulisan angka. Karena writematrix/readmatrix (MATLAB R2019a+) tidak ada di Octave, contoh memakai guard exist seperti biasa:

matlab
M = [id nilai];
if exist('writematrix') ~= 0
  writematrix(M, 'data.csv');        % MATLAB R2019a+
  fprintf('data.csv ditulis dengan writematrix\n');
else
  dlmwrite('data.csv', M, 'delimiter', ',', 'precision', '%.2f');
  fprintf('data.csv ditulis dengan dlmwrite\n');
end
if exist('readmatrix') ~= 0
  D = readmatrix('data.csv');        % MATLAB R2019a+
else
  D = dlmread('data.csv');           % padanan klasik
end
fprintf('roundtrip data.csv: %dx%d, D(2,2)=%.2f\n', size(D, 1), size(D, 2), D(2, 2));
fprintf('nilai identik: %d\n', isequal(D, M));

Output yang Dihasilkan (jalur klasik yang aktif saat diuji di Octave — di MATLAB label menjadi writematrix, nilainya sama):

text
data.csv ditulis dengan dlmwrite
roundtrip data.csv: 3x2, D(2,2)=92.30
nilai identik: 1

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (M = [id nilai]): dua kolom numerik digabung menjadi matriks 3×2 — dlmwrite hanya menerima data numerik, kolom nama tidak ikut.
  2. Baris 6 ('precision', '%.2f'): seluruh angka ditulis dua desimal — 87.5 menjadi 87.50 di dalam berkas; hasil roundtrip isequal tetap 1 karena 87.50 terbaca kembali sebagai 87.5.
  3. Baris 14 (isequal(D, M)): uji roundtrip — nilai identik elemen demi elemen berarti tidak ada angka yang rusak di perjalanan.

Di MATLAB modern, tabel bernama kolom ditulis dengan writetable (kode berikut MATLAB-only di Octave — hanya berjalan di MATLAB):

matlab
% MATLAB-only di Octave: writetable menyimpan header + data bertipe
T = table(id, nama, nilai);
writetable(T, 'data.csv');            % hasil: baris "id,nama,nilai" + 3 baris data
writetable(T, 'data.xlsx', 'Sheet', 'Laporan');

Fungsi writetable menulis header id,nama,nilai otomatis dari nama variabel, dan untuk .xlsx menempatkan tabel di dalam sheet Excel bernama Laporan — dua hal yang dlmwrite tidak bisa.

Menyimpan Workspace dengan save #

Berkas .mat adalah format asli MATLAB: variabel disimpan lengkap dengan nama, tipe, dan dimensinya — cell array, struct, seluruh workspace sekalipun. Mekanismenya: save(namaBerkas, variabel, versi) menulis variabel yang disebut namanya; load mengembalikannya ke workspace tanpa perlu parsing:

matlab
suhuKota = [28.5 29.0 27.8];
namaKota = {'Bandung', 'Yogyakarta', 'Malang'};
save('data.mat', 'suhuKota', 'namaKota', '-v7');
clear suhuKota namaKota
S = load('data.mat');
fprintf('data.mat: %s %.1f derajat\n', S.namaKota{2}, S.suhuKota(2));
fprintf('variabel tersimpan: %d\n', numel(fieldnames(S)));

Output yang Dihasilkan:

text
data.mat: Yogyakarta 29.0 derajat
variabel tersimpan: 2

Mari kita bedah baris-baris kode di atas:

  1. Baris 3 (save(..., '-v7')): dua variabel — vektor double dan cell array — tersimpan dalam satu berkas; fieldnames setelah load membuktikan keduanya kembali.
  2. Baris 4 (clear): variabel asli dihapus sebelum load — bukti bahwa nilai benar-benar datang dari berkas, bukan tersisa di memori.
  3. Baris 5 (S = load(...)): bentuk struct mengembalikan semua variabel dalam satu wadah S — load tanpa keluaran menempatkannya langsung ke workspace.
VersiDasar teknisBatas ukuranKapan dipakai
-v7 (default)biner terkompresi2 GB per variabelhampir semua keperluan
-v7.3HDF5di atas 2 GB, 64-bitdataset raksasa; satu-satunya versi yang bisa diakses parsial lewat matfile

Versi -v7.3 lebih lambat ditulis dan berkasnya kerap lebih besar — jangan memakainya tanpa alasan. Octave belum mendukung penulisan -v7.3, tetapi membaca berkas -v7 seperti contoh di atas berjalan mulus.

Newline: Windows vs Unix #

Satu baris teks diakhiri satu karakter \n (LF, byte 10) di Unix/Linux/macOS, tetapi dua karakter \r\n (CR+LF, byte 13 lalu 10) di Windows. Mekanismenya: fprintf menulis byte persis seperti yang diminta — mode biner 'w' tidak menambahkan apa pun:

matlab
fid = fopen('crlf.txt', 'w');
fprintf(fid, 'windows\r\n');
fclose(fid);
fid = fopen('crlf.txt', 'rb');
b = fread(fid, inf, 'uint8');
fclose(fid);
fprintf('byte akhir \\r \\n: %d %d\n', b(end-1), b(end));

Output yang Dihasilkan:

text
byte akhir \r \n: 13 10

Mari kita bedah baris-baris kode di atas:

  1. Baris 2 ('windows\r\n'): escape \r (13) dan \n (10) ditulis berdampingan — berkas ini tampil rapi di Notepad Windows klasik.
  2. Baris 5-6 (fread ... 'uint8'): teknik biner chapter sebelumnya dipakai untuk membedah isi berkas — bukti konkret bahwa \n tunggal hanyalah byte 10.
  3. Alternatif mode teks: di Windows, membuka berkas dengan mode 'wt' membuat MATLAB menyisipkan \r otomatis sebelum tiap \n — di Linux kedua mode menghasilkan byte yang sama.

Memilih Format Keluaran #

FormatFungsi tulisTerbaca olehCocok untuk
.txtfprintfmanusia, editor apa punlaporan, log dengan format bebas
.csvwritematrix/writetable (MATLAB), dlmwritespreadsheet, database, semua bahasapertukaran tabel lintas aplikasi
.matsaveMATLAB, Octavehasil antara yang menyimpan tipe & nama variabel
.jsonjsonencode + fprintf (chapter Membaca File JSON)browser, API, bahasa modernkonfigurasi dan pertukaran terstruktur
.xlsxwritetable (MATLAB)Excel, LibreOfficelaporan bisnis berformat

Aturan praktisnya: manusia membaca .txt/.xlsx, mesin lain membaca .csv/.json, dan analisis MATLAB-pada-MATLAB memakai .mat karena tipe data tidak perlu ditafsirkan ulang.

Berkas contoh.m pada bagian bawah halaman merangkai seluruh alur — laporan terformat, append, roundtrip CSV dengan guard, roundtrip .mat, uji newline CRLF, lalu pembersihan berkas demo — dalam satu script.

Ringkasan #

fprintf ke berkas memberi kendali format penuh dengan mode 'w' menimpa dan 'a' menambah; dlmwrite menulis tabel numerik dengan delimiter dan presisi pilihan, sementara MATLAB modern menawarkan writematrix/writetable; save -v7 menyimpan variabel lengkap dengan tipe dan namanya, -v7.3 untuk data di atas 2 GB. Newline \n vs \r\n diurus dengan mode teks 'wt' atau escape eksplisit. Ketika data tumbuh melebihi memori, cara berpikirnya berubah — kita bahas di chapter Bekerja dengan Dataset Besar.