P Pascal dan Algoritma
Modul 5 dari 50 Roadmap
Modul 05 - Fase Dasar

Input/Output dan Pemformatan Teks

Modul ini membahas cara program berkomunikasi dengan pengguna melalui keyboard dan layar. Anda akan mempelajari prosedur read, readln, write, dan writeln, teknik pemformatan keluaran dengan lebar field dan jumlah desimal, karakter escape, serta penanganan masalah umum saat membaca input. Kemampuan ini akan membuat program Anda tampil rapi dan profesional.

Estimasi 120 menit Tingkat Dasar 2 Flowchart 4 Program Pascal 5 Latihan
01

Tujuan Pembelajaran

Kompetensi yang ingin dicapai setelah menyelesaikan modul ini

Setelah menyelesaikan modul ini, mahasiswa diharapkan mampu:

  1. Membedakan perilaku read dan readln.
  2. Membedakan perilaku write dan writeln.
  3. Mengontrol pemformatan keluaran dengan sintaks :lebar dan :lebar:desimal.
  4. Menggunakan karakter escape dan kode kendali untuk mengatur tampilan.
  5. Menangani masalah umum saat membaca input dari keyboard, termasuk baris baru yang tertinggal.
  6. Memformat keluaran numerik agar rata dan mudah dibaca.
  7. Menggunakan unit crt untuk membersihkan layar dan pengaturan kursor.
  8. Membaca input karakter tunggal dan menanganinya secara benar.
  9. Membuat tabel keluaran yang rapi dengan lebar kolom tetap.
  10. Menghindari kesalahan umum saat membaca angka dan string secara bergantian.
02

Capaian Pembelajaran

Indikator ketercapaian dan kaitan dengan modul selanjutnya

Capaian Pembelajaran Mata Kuliah

Mahasiswa mampu merancang antarmuka teks yang rapi dan interaktif, melakukan pembacaan input yang aman, serta menghasilkan keluaran terformat sesuai kebutuhan presentasi data.

Indikator Ketercapaian Modul

Kode Indikator Bukti
IK-5.1 Membedakan penggunaan read dan readln secara tepat Latihan 1 dan 2
IK-5.2 Memformat keluaran dengan lebar field dan desimal Latihan 3 dan 4
IK-5.3 Membuat tabel keluaran rapi dengan lebar kolom tetap Latihan 4 dan studi kasus
IK-5.4 Menangani masalah baris baru yang tertinggal Latihan 5
IK-5.5 Menggunakan karakter escape dan unit crt dengan benar Jawaban latihan teori
Kaitan dengan Modul Berikutnya

Kemampuan input/output yang baik sangat penting untuk seluruh modul berikutnya. Mulai Modul 6, kita akan sering menampilkan hasil percabangan dan perulangan; format keluaran yang rapi akan mempermudah verifikasi program. Modul 25 akan meluaskan konsep ini ke pembacaan dan penulisan berkas.

03

Materi Teori

Prosedur input/output, pemformatan, dan karakter kendali

3.1 Empat Prosedur Dasar Input/Output

Pascal menyediakan empat prosedur utama untuk berkomunikasi dengan pengguna. Keempatnya memiliki pasangan yang berbeda dalam hal perilaku.

Prosedur Arah Perilaku Setelah Operasi
write Keluaran Menampilkan tanpa menambah baris baru
writeln Keluaran Menampilkan lalu pindah ke baris berikutnya
read Masukan Membaca sampai ada pemisah (spasi/baris baru), pemisah tetap di stream
readln Masukan Membaca sampai akhir baris, membuang pemisah baris

Contoh Perbedaan write vs writeln

write_vs_writeln.pasPascal
write('Baris pertama tanpa newline. ');
write('Ini masih baris yang sama.');
writeln;
writeln('Baris berikutnya dimulai di sini.');
writeln('Baris ini juga punya newline di akhir.');

Keluaran:

Baris pertama tanpa newline. Ini masih baris yang sama.
Baris berikutnya dimulai di sini.
Baris ini juga punya newline di akhir.

Contoh Perbedaan read vs readln

read_vs_readln.pasPascal
var
  a, b, c: integer;

begin
  write('Masukkan tiga angka dipisah spasi: ');
  read(a);
  read(b);
  read(c);
  writeln('a = ', a, ', b = ', b, ', c = ', c);
end.

Bila pengguna mengetik 10 20 30 lalu menekan Enter, ketiga prosedur read akan membaca tiga angka secara berurutan tanpa perlu menekan Enter di antara angka. Namun bila memakai readln, hanya angka pertama yang akan tersimpan; sisanya diabaikan.

Praktik yang Dianjurkan

Untuk masukan dari keyboard, hampir selalu gunakan readln ketimbang read. Perilaku readln yang membuang baris setelah pembacaan lebih intuitif dan mencegah masalah baris baru yang tertinggal. Gunakan read hanya ketika Anda benar-benar perlu membaca banyak nilai dari satu baris secara berurutan.

3.2 Pemformatan Keluaran: Sintaks Titik Dua

Pascal menyediakan cara elegan untuk memformat keluaran melalui sintaks titik dua setelah nilai yang akan ditampilkan.

a. Format Lebar Field

Untuk tipe numerik dan string, Anda dapat menentukan lebar field minimum dengan :lebar.

format_lebar.pasPascal
var
  n: integer;

begin
  n := 42;
  writeln('[', n, ']');         { [42] }
  writeln('[', n:5, ']');       { [   42] }
  writeln('[', n:8, ']');       { [      42] }
  writeln('[', n:1, ']');       { [42], lebar kurang dari panjang tetap ditampilkan }
end.

Keluaran:

[42]
[   42]
[      42]
[42]

Perhatikan bahwa nilai ditampilkan rata kanan dalam field. Bila nilai lebih panjang dari lebar field, seluruh nilai tetap ditampilkan tanpa pemotongan.

b. Format Lebar dan Desimal untuk Real

Untuk nilai real, sintaksnya adalah :lebar:desimal. Bagian desimal menentukan berapa angka di belakang koma yang ditampilkan.

format_real.pasPascal
var
  pi: double;

begin
  pi := 3.14159265358979;

  writeln('[', pi:0:0, ']');    { [3] }
  writeln('[', pi:0:2, ']');    { [3.14] }
  writeln('[', pi:0:4, ']');    { [3.1416] }
  writeln('[', pi:0:10, ']');   { [3.1415926536] }
  writeln('[', pi:10:2, ']');   { [      3.14] }
  writeln('[', pi:15:6, ']');   { [       3.141593] }
end.

Keluaran:

[3]
[3.14]
[3.1416]
[3.1415926536]
[      3.14]
[       3.141593]
Arti Lebar 0

Lebar 0 berarti "gunakan lebar minimum yang diperlukan". Ini berguna ketika Anda hanya ingin mengontrol jumlah desimal tanpa mempedulikan perataan.

c. Pemformatan String

String juga dapat diformat dengan lebar field. Perilaku perataannya rata kiri (berbeda dengan numerik yang rata kanan).

format_string.pasPascal
var
  s: string;

begin
  s := 'Pascal';
  writeln('[', s, ']');         { [Pascal] }
  writeln('[', s:10, ']');      { [Pascal    ] }
  writeln('[', s:3, ']');       { [Pascal] }
end.

3.3 Membuat Tabel Keluaran yang Rapi

Dengan menggabungkan format lebar, kita dapat membuat tabel keluaran yang rapi seperti pada laporan keuangan.

tabel_rapi.pasPascal
writeln('No  Nama Barang       Harga       Jumlah');
writeln('------------------------------------------');
writeln(1:2, '  ', 'Laptop'.PadRight(18), 8500000:12:2, 3:10);
writeln(2:2, '  ', 'Mouse'.PadRight(18), 150000:12:2, 5:10);
writeln(3:2, '  ', 'Keyboard'.PadRight(18), 250000:12:2, 2:10);

Perhatikan penggunaan PadRight (fungsi dari unit strutils) untuk meratakan string ke kanan. Alternatif tanpa unit tambahan adalah dengan :lebar.

tabel_rapi_manual.pasPascal
writeln('No  Nama Barang            Harga      Jumlah');
writeln('----------------------------------------------');
writeln(1:2, '  ', 'Laptop':-18, 8500000:12:2, 3:10);
writeln(2:2, '  ', 'Mouse':-18, 150000:12:2, 5:10);
writeln(3:2, '  ', 'Keyboard':-18, 250000:12:2, 2:10);

Tanda negatif pada lebar string (-18) berarti rata kiri. Ini adalah fitur khas Free Pascal yang tidak ada di semua varian Pascal.

3.4 Karakter Escape dan Kode Kendali

Karakter escape adalah karakter khusus yang tidak dapat diketik langsung dari keyboard. Dalam Pascal, karakter ini ditulis dengan tanda # diikuti kode ASCII-nya, atau melalui konstanta yang didefinisikan.

Karakter Kode Notasi Pascal Fungsi
Newline10#10 atau LineEndingPindah baris
Carriage Return13#13Kembali ke awal baris
Tab9#9Tab horizontal
Bell7#7Bunyi bel (bila didukung)
Backspace8#8Mundur satu karakter
Escape27#27Kode escape terminal
Form Feed12#12Pindah halaman
karakter_escape.pasPascal
begin
  writeln('Baris pertama');
  writeln('Baris kedua');

  { Karakter tab }
  writeln('Nama', #9, 'Umur', #9, 'Kota');
  writeln('Andi', #9, 20, #9, 'Bandung');

  { Bunyi bel }
  writeln('Perhatian!', #7);

  { Gabungan newline di dalam string }
  writeln('Baris A', #10, 'Baris B');
end.

3.5 Unit crt untuk Pengaturan Layar

Unit crt menyediakan prosedur untuk mengendalikan layar. Unit ini harus didaftarkan di klausa uses.

Prosedur/Fungsi Fungsi
ClrScrMembersihkan seluruh layar
GotoXY(x, y)Memindahkan kursor ke koordinat (x, y)
WhereXMengembalikan posisi kolom kursor saat ini
WhereYMengembalikan posisi baris kursor saat ini
TextColor(warna)Mengatur warna teks
TextBackground(warna)Mengatur warna latar
Delay(ms)Menunda eksekusi selama milidetik
ReadKeyMembaca satu tombol tanpa menampilkannya
KeyPressedMemeriksa apakah ada tombol yang ditekan
demo_crt.pasPascal
program DemoCrt;

uses
  crt;

begin
  ClrScr;

  GotoXY(20, 5);
  TextColor(Yellow);
  writeln('Judul Program');

  GotoXY(20, 7);
  TextColor(White);
  writeln('Tekan tombol apa saja untuk melanjutkan...');

  ReadKey;
  ClrScr;
  writeln('Layar telah dibersihkan.');

  TextColor(LightGreen);
  writeln('Warna teks berubah menjadi hijau terang.');
end.

3.6 Membaca Karakter Tunggal dengan ReadKey

Prosedur readln selalu menunggu Enter sebelum melanjutkan. Untuk membaca satu karakter tanpa menunggu Enter, gunakan ReadKey dari unit crt.

readkey.pasPascal
program DemoReadKey;

uses
  crt;

var
  tombol: char;

begin
  write('Tekan tombol apa saja: ');
  tombol := ReadKey;
  writeln;
  writeln('Anda menekan: ', tombol);
  writeln('Kode ASCII: ', Ord(tombol));
end.

3.7 Penanganan Masalah Baris Baru

Salah satu masalah paling umum dalam input/output Pascal adalah baris baru yang tertinggal setelah pembacaan angka. Perhatikan contoh berikut.

masalah_baris_baru.pasPascal
var
  umur: integer;
  nama: string;

begin
  write('Masukkan umur: ');
  readln(umur);          { Membaca angka lalu membuang Enter }

  write('Masukkan nama: ');
  readln(nama);          { Aman, karena baris sudah bersih }

  writeln('Umur: ', umur);
  writeln('Nama: ', nama);
end.

Masalah muncul ketika kita mencampur read dan readln, atau ketika membaca angka dengan read lalu mencoba membaca string dengan readln.

masalah_baris_baru_buruk.pasPascal
var
  umur: integer;
  nama: string;

begin
  write('Masukkan umur: ');
  read(umur);            { Enter ditinggal di buffer }

  write('Masukkan nama: ');
  readln(nama);          { Langsung membaca string kosong }

  writeln('Nama: ', nama);   { Akan tampil kosong }
end.
Solusi

Ada dua solusi: (1) selalu gunakan readln untuk membaca input dari keyboard, atau (2) tambahkan readln; setelah read untuk membuang baris yang tertinggal.

solusi.pasPascal
write('Masukkan umur: ');
readln(umur);              { Menggunakan readln }

{ atau }

write('Masukkan umur: ');
read(umur);
readln;                    { Buang sisa baris }

3.8 Kesalahan Umum Input/Output

  1. Mencampur read dan readln. Menyebabkan baris baru tertinggal dan input berikutnya menjadi kosong.
  2. Membaca string dengan spasi. readln membaca seluruh baris termasuk spasi. Ini umumnya yang diinginkan, tetapi berbeda dengan read yang berhenti pada spasi pertama.
  3. Membandingkan hasil read dengan nilai salah. Bila pengguna mengetik huruf ketika program mengharapkan angka, perilaku tidak terdefinisi dan bisa menyebabkan crash.
  4. Lupa karakter penutup. Setiap string literal harus diapit petik tunggal yang berpasangan.
  5. Mengabaikan kegagalan konversi. Untuk input angka dari string, gunakan Val dengan pemeriksaan kode kesalahan.
  6. Menampilkan real tanpa kontrol desimal. Nilai real default menampilkan banyak digit; gunakan :0:2 atau format lain untuk keterbacaan.
  7. Menggunakan CrLf di tengah writeln. Cukup gunakan writeln atau LineEnding untuk portabilitas.
  8. Menampilkan boolean tanpa konversi. Boolean akan ditampilkan sebagai TRUE/FALSE. Bila ingin teks lain, konversi manual.

3.9 Perbedaan Free Pascal dan Turbo Pascal

Aspek Turbo Pascal Free Pascal
Lebar string negatifTidak didukungDidukung (rata kiri)
Unit crtAdaAda, kompatibel
ReadKeyAdaAda, kompatibel
Karakter #10DidukungDidukung, plus LineEnding
Pemformatan :0:2DidukungDidukung
Unicode outputTidakDidukung via UnicodeString
04

Algoritma dan Flowchart

Alur input/output dan pemformatan keluaran

4.1 Flowchart Alur Input, Proses, Output

Diagram berikut menggambarkan pola klasik program: menerima masukan, mengolah, lalu menampilkan keluaran.

flowchart TD
    A(["Mulai"]) --> B[/"Tampilkan prompt"/]
    B --> C[/"Baca masukan dengan readln"/]
    C --> D["Proses data"]
    D --> E["Format keluaran
dengan lebar field"] E --> F[/"Tampilkan hasil"/] F --> G{"Ada input lagi?"} G -- "Ya" --> B G -- "Tidak" --> H(["Selesai"])

Gambar 4.1 - Pola umum input, proses, dan output

4.2 Flowchart Penanganan Baris Baru

Diagram berikut menggambarkan alur pembacaan input yang aman dengan readln, dan masalah yang muncul bila menggunakan read tanpa membuang baris baru.

flowchart TD
    A(["Input berikutnya"]) --> B{"Gunakan
read atau
readln?"} B -- "read" --> C["Angka terbaca,
baris baru tertinggal"] C --> D["Input berikutnya
akan membaca baris kosong"] D --> E["Hasil tidak sesuai"] B -- "readln" --> F["Angka terbaca,
baris baru dibuang"] F --> G["Input berikutnya
membaca dengan benar"] G --> H["Hasil sesuai"] E --> I(["Perlu perbaikan"]) H --> J(["Selesai"])

Gambar 4.2 - Perbandingan alur read dan readln

05

Pseudocode

Representasi algoritmik dari input dan pemformatan keluaran

5.1 Pseudocode Input Data Mahasiswa dengan Validasi Panjang

PROGRAM InputDataMahasiswa
{ Membaca data mahasiswa dan menampilkannya dengan format rapi }

DEKLARASI
  nama       : string
  nim        : string
  nilai      : real
  panjangNm  : integer

ALGORITMA
  write("Masukkan nama mahasiswa : ")
  read(nama)

  panjangNm <- length(nama)
  jika panjangNm < 3 maka
    write("Peringatan: nama terlalu pendek")
  akhir jika

  write("Masukkan NIM            : ")
  read(nim)

  write("Masukkan nilai ujian    : ")
  read(nilai)

  write("========================================")
  write("Nama   : ", nama)
  write("NIM    : ", nim)
  write("Nilai  : ", nilai diformat 2 desimal)
  write("========================================")
END

5.2 Pseudocode Menampilkan Tabel Nilai

PROGRAM TabelNilai
{ Menampilkan tabel nilai dengan format kolom tetap }

DEKLARASI
  nama1, nama2, nama3 : string
  nilai1, nilai2, nilai3 : real

ALGORITMA
  write("Nama mahasiswa 1: ")
  read(nama1)
  write("Nilai mahasiswa 1: ")
  read(nilai1)

  write("Nama mahasiswa 2: ")
  read(nama2)
  write("Nilai mahasiswa 2: ")
  read(nilai2)

  write("Nama mahasiswa 3: ")
  read(nama3)
  write("Nilai mahasiswa 3: ")
  read(nilai3)

  write("==========================================")
  write("No  Nama                 Nilai")
  write("------------------------------------------")
  write("1   ", nama1 rata kiri 20, " ", nilai1 2 desimal)
  write("2   ", nama2 rata kiri 20, " ", nilai2 2 desimal)
  write("3   ", nama3 rata kiri 20, " ", nilai3 2 desimal)
  write("==========================================")
END

5.3 Pseudocode Menu Interaktif Sederhana

PROGRAM MenuInteraktif
{ Menampilkan menu dan membaca pilihan pengguna }

DEKLARASI
  pilihan : char

ALGORITMA
  write("========================================")
  write("MENU UTAMA")
  write("========================================")
  write("1. Tampilkan data")
  write("2. Tambah data")
  write("3. Hapus data")
  write("4. Keluar")
  write("========================================")
  write("Pilihan Anda (1-4): ")
  read(pilihan)

  write("Anda memilih: ", pilihan)
END
06

Contoh Kode Pascal Lengkap

Empat program untuk mendemonstrasikan input/output dan pemformatan

6.1 Program Demonstrasi Format Keluaran

demo_format.pas Pascal
program DemoFormat;
{ Mendemonstrasikan pemformatan keluaran di Pascal }

var
  n: integer;
  r: double;
  s: string;

begin
  n := 42;
  r := 3.14159265358979;
  s := 'Pascal';

  writeln('=== Format Integer ===');
  writeln('[', n, ']');
  writeln('[', n:5, ']');
  writeln('[', n:8, ']');
  writeln('[', n:2, ']');

  writeln;
  writeln('=== Format Real ===');
  writeln('[', r:0:0, ']');
  writeln('[', r:0:2, ']');
  writeln('[', r:0:4, ']');
  writeln('[', r:0:10, ']');
  writeln('[', r:15:6, ']');

  writeln;
  writeln('=== Format String ===');
  writeln('[', s, ']');
  writeln('[', s:10, ']');
  writeln('[', s:3, ']');
  writeln('[', s:-10, ']');
end.

Keluaran:

=== Format Integer ===
[42]
[   42]
[      42]
[42]

=== Format Real ===
[3]
[3.14]
[3.1416]
[3.1415926536]
[       3.141593]

=== Format String ===
[Pascal]
[Pascal    ]
[Pascal]
[Pascal    ]

6.2 Program Tabel Nilai Mahasiswa

tabel_nilai.pas Pascal
program TabelNilai;
{ Menampilkan daftar nilai dalam format tabel rapi }

const
  LEBAR_NAMA = 22;
  LEBAR_NILAI = 8;

var
  nama1, nama2, nama3: string;
  nilai1, nilai2, nilai3: real;

begin
  writeln('Masukkan data tiga mahasiswa');
  writeln('----------------------------------------');
  writeln;

  write('Nama mahasiswa 1: ');
  readln(nama1);
  write('Nilai mahasiswa 1: ');
  readln(nilai1);

  write('Nama mahasiswa 2: ');
  readln(nama2);
  write('Nilai mahasiswa 2: ');
  readln(nilai2);

  write('Nama mahasiswa 3: ');
  readln(nama3);
  write('Nilai mahasiswa 3: ');
  readln(nilai3);

  writeln;
  writeln('================================================');
  writeln('No  Nama                  Nilai');
  writeln('------------------------------------------------');

  writeln(1:2, '  ', nama1:-(LEBAR_NAMA), nilai1:LEBAR_NILAI:2);
  writeln(2:2, '  ', nama2:-(LEBAR_NAMA), nilai2:LEBAR_NILAI:2);
  writeln(3:2, '  ', nama3:-(LEBAR_NAMA), nilai3:LEBAR_NILAI:2);

  writeln('================================================');
end.

Contoh keluaran:

Masukkan data tiga mahasiswa
----------------------------------------

Nama mahasiswa 1: Andi Wijaya
Nilai mahasiswa 1: 85.5
Nama mahasiswa 2: Budi Santoso
Nilai mahasiswa 2: 92.75
Nama mahasiswa 3: Citra Dewi
Nilai mahasiswa 3: 78

================================================
No  Nama                  Nilai
------------------------------------------------
 1  Andi Wijaya             85.50
 2  Budi Santoso            92.75
 3  Citra Dewi              78.00
================================================

6.3 Program dengan Format Rupiah

format_rupiah.pas Pascal
program FormatRupiah;
{ Menampilkan nilai uang dalam format rapi }

var
  namaBarang1, namaBarang2, namaBarang3: string;
  harga1, harga2, harga3: currency;
  total: currency;

begin
  write('Barang 1: ');
  readln(namaBarang1);
  write('Harga 1 : ');
  readln(harga1);

  write('Barang 2: ');
  readln(namaBarang2);
  write('Harga 2 : ');
  readln(harga2);

  write('Barang 3: ');
  readln(namaBarang3);
  write('Harga 3 : ');
  readln(harga3);

  total := harga1 + harga2 + harga3;

  writeln;
  writeln('============================================');
  writeln('No  Barang                Harga');
  writeln('--------------------------------------------');
  writeln(1:2, '  ', namaBarang1:-20, harga1:18:2);
  writeln(2:2, '  ', namaBarang2:-20, harga2:18:2);
  writeln(3:2, '  ', namaBarang3:-20, harga3:18:2);
  writeln('--------------------------------------------');
  writeln('Total'.PadLeft(24), total:18:2);
  writeln('============================================');
end.
Fungsi PadLeft

PadLeft dan PadRight adalah fungsi dari unit strutils. Untuk menggunakannya, tambahkan strutils ke klausa uses. Alternatif tanpa unit tambahan adalah dengan format lebar field.

6.4 Program dengan ReadKey untuk Menu

menu_readkey.pas Pascal
program MenuReadKey;
{ Menu interaktif sederhana dengan ReadKey }

uses
  crt;

var
  pilihan: char;

begin
  ClrScr;

  writeln('========================================');
  writeln('         MENU UTAMA');
  writeln('========================================');
  writeln('1. Tampilkan data');
  writeln('2. Tambah data');
  writeln('3. Hapus data');
  writeln('4. Keluar');
  writeln('========================================');
  write('Pilihan Anda (1-4): ');

  pilihan := ReadKey;
  writeln(pilihan);

  writeln;
  case pilihan of
    '1': writeln('Anda memilih: Tampilkan data');
    '2': writeln('Anda memilih: Tambah data');
    '3': writeln('Anda memilih: Hapus data');
    '4': writeln('Anda memilih: Keluar');
  else
    writeln('Pilihan tidak valid');
  end;

  writeln;
  writeln('Tekan tombol apa saja untuk keluar...');
  ReadKey;
end.

Perhatikan bahwa ReadKey membaca satu tombol tanpa menampilkannya. Karena itu, kita perlu mencetak karakter yang dibaca secara manual dengan writeln(pilihan).

07

Penjelasan Kode Baris per Baris

Membedah program TabelNilai dan MenuReadKey secara rinci

7.1 Program TabelNilai

Baris Kode Penjelasan
5-6 LEBAR_NAMA = 22;
LEBAR_NILAI = 8;
Dua konstanta untuk lebar kolom. Dengan menggunakan konstanta, kita dapat mengubah lebar kolom di satu tempat tanpa mengubah setiap baris writeln.
8-10 nama1, nama2, nama3: string;
nilai1, nilai2, nilai3: real;
Tiga variabel string dan tiga variabel real. Karena baru tiga mahasiswa, kita memakai variabel terpisah, bukan array. Array akan dibahas pada Modul 16.
13-29 write('Nama mahasiswa 1: ');
readln(nama1);
...
Enam pasang prompt dan readln untuk mengumpulkan data. Perhatikan bahwa setiap prompt diakhiri dengan spasi sebelum tanda petik penutup, sehingga kursor pengguna berada tepat setelah titik dua dengan jarak satu spasi.
33-35 writeln('====...');
writeln('No Nama ...');
writeln('-----...');
Header tabel. Spasi di dalam string literal ditulis manual untuk menyelaraskan kolom dengan data di bawahnya.
37 writeln(1:2, ' ', nama1:-(LEBAR_NAMA), nilai1:LEBAR_NILAI:2); Baris data pertama. Formatnya:
  • 1:2 - nomor urut lebar 2, rata kanan
  • ' ' - dua spasi pemisah
  • nama1:-(LEBAR_NAMA) - string rata kiri lebar 22
  • nilai1:LEBAR_NILAI:2 - real lebar 8 dengan 2 desimal
38-39 writeln(2:2, ' ', nama2:-(LEBAR_NAMA), nilai2:LEBAR_NILAI:2);
writeln(3:2, ...);
Pola yang sama untuk baris kedua dan ketiga.
41 writeln('====...'); Penutup tabel. Panjang garis harus sesuai dengan lebar total kolom agar terlihat rapi. Perhatikan bahwa panjang garis 48 karakter (2 + 2 + 22 + 8 + 14 spasi tersembunyi).

7.2 Program MenuReadKey

Baris Kode Penjelasan
5-6 uses
crt;
Mendaftarkan unit crt agar prosedur seperti ClrScr dan ReadKey tersedia.
11 ClrScr; Membersihkan layar sebelum menampilkan menu.
13-19 writeln('====...');
writeln('MENU UTAMA');
...
Menampilkan menu dengan format rapi. Judul 'MENU UTAMA' diberi spasi tambahan di kiri agar terlihat di tengah.
20 write('Pilihan Anda (1-4): '); Menggunakan write (bukan writeln) agar kursor tetap di baris yang sama.
22 pilihan := ReadKey; Membaca satu karakter dari keyboard. Karena ReadKey tidak menampilkan karakter yang ditekan, kita perlu menampilkannya secara manual di baris berikutnya.
23 writeln(pilihan); Menampilkan kembali karakter yang baru dibaca, memberi umpan balik visual kepada pengguna.
26-32 case pilihan of
'1': ...
'2': ...
...
end;
Struktur case memilih aksi berdasarkan nilai pilihan. Kasus else menangani pilihan yang tidak dikenali. Percabangan case dibahas lengkap pada Modul 7.
35-36 writeln('Tekan tombol apa saja...');
ReadKey;
Menunggu pengguna menekan tombol sebelum program berakhir. Tanpa ini, jendela konsol akan tertutup segera setelah program selesai bila dijalankan dari IDE.
Pelajaran Kunci

Input/output bukan sekadar teknis, tetapi juga soal pengalaman pengguna. Prompt yang jelas, format yang konsisten, dan umpan balik visual adalah ciri program yang dipikirkan dengan baik. Biasakan diri untuk selalu merancang tampilan sebelum menulis kode.

08

Latihan Soal

Lima soal dengan tingkat kesulitan bertingkat

1

Eksperimen read vs readln

Mudah

Buat tiga program kecil dengan skenario berikut, lalu catat hasilnya.

Skenario A:

skenario_a.pasPascal
var a, b: integer;
begin
  write('Dua angka: ');
  read(a);
  read(b);
  writeln('a = ', a, ', b = ', b);
end.

Skenario B:

skenario_b.pasPascal
var a, b: integer;
begin
  write('Angka pertama: ');
  readln(a);
  write('Angka kedua: ');
  readln(b);
  writeln('a = ', a, ', b = ', b);
end.

Skenario C:

skenario_c.pasPascal
var a: integer;
    s: string;
begin
  write('Angka: ');
  read(a);
  write('Nama: ');
  readln(s);
  writeln('Angka: ', a);
  writeln('Nama : ', s);
end.

Pertanyaan analisis: pada Skenario C, mengapa s menjadi kosong? Bagaimana cara memperbaikinya?

2

Kartu Ucapan Terformat

Mudah

Buat program yang menerima nama penerima, nama pengirim, dan pesan singkat. Kemudian tampilkan kartu ucapan dengan format berikut:

+------------------------------------------+
|                                          |
|   Untuk  : Andi Wijaya                   |
|                                          |
|   Pesan  : Selamat ulang tahun!          |
|            Semoga sukses selalu.         |
|                                          |
|   Dari   : Budi                          |
|                                          |
+------------------------------------------+

Ketentuan:

  • Gunakan lebar field untuk meratakan string.
  • Buat konstanta untuk garis atas dan bawah.
  • Panjang total kartu harus konsisten di semua baris.
3

Laporan Penjualan dengan Format Rupiah

Sedang

Buat program yang menerima data penjualan tiga produk: nama produk, harga satuan, dan jumlah terjual. Tampilkan laporan dengan format tabel berikut:

================================================================
                    LAPORAN PENJUALAN
================================================================
No  Nama Produk             Harga    Jumlah     Subtotal
----------------------------------------------------------------
 1  Laptop                8500000         3     25500000.00
 2  Mouse                  150000        10      1500000.00
 3  Keyboard               250000         5      1250000.00
----------------------------------------------------------------
Total                                             28250000.00
================================================================

Ketentuan:

  • Gunakan currency untuk semua nilai uang.
  • Hitung subtotal = harga × jumlah.
  • Hitung total dari semua subtotal.
  • Semua nilai uang ditampilkan dengan 2 angka desimal.
  • Kolom harga rata kanan, kolom nama rata kiri.
4

Tabel Konversi Suhu

Sedang

Buat program yang menampilkan tabel konversi suhu dari Celsius ke Fahrenheit dan Kelvin, untuk suhu 0, 10, 20, ..., 100 derajat.

Format tabel:

==========================================
TABEL KONVERSI SUHU
==========================================
Celsius   Fahrenheit        Kelvin
------------------------------------------
      0        32.00        273.15
     10        50.00        283.15
     20        68.00        293.15
    ...
    100       212.00        373.15
==========================================

Ketentuan:

  • Karena belum mempelajari perulangan, tulis setiap baris secara manual (0, 10, 20, ..., 100 = 11 baris).
  • Rumus Fahrenheit: (c * 9 / 5) + 32.
  • Rumus Kelvin: c + 273.15.
  • Semua hasil ditampilkan dengan 2 desimal.

Pertanyaan analisis: kolom mana yang sebaiknya rata kanan, dan kolom mana yang rata kiri? Mengapa?

5

Perbaikan Program Input Bermasalah

Sulit

Program berikut memiliki beberapa masalah terkait input/output. Identifikasi semua masalah, jelaskan, lalu tuliskan versi perbaikan.

input_kacau.pasPascal
program InputKacau;

uses crt;

var
  nama: string;
  umur: integer;
  tinggi: real;
  golDarah: char;

begin
  write('Masukkan nama: ');
  read(nama);

  write('Masukkan umur: ');
  read(umur);

  write('Masukkan tinggi (cm): ');
  read(tinggi);

  write('Masukkan golongan darah: ');
  read(golDarah);

  writeln('Nama  : ', nama);
  writeln('Umur  : ', umur);
  writeln('Tinggi: ', tinggi);
  writeln('Gol   : ', golDarah);
end.

Ketentuan:

  • Sebutkan setiap masalah pada program di atas.
  • Jelaskan mengapa setiap masalah menyebabkan bug.
  • Tuliskan versi perbaikan lengkap.

Pertanyaan analisis: pada program di atas, mengapa variabel umur dan tinggi kemungkinan besar akan berisi nilai yang salah? Bagaimana cara memperbaikinya dengan pendekatan yang berbeda dari sekadar mengganti read menjadi readln?

09

Studi Kasus

Nota Restoran "Rasa Nusantara"

9.1 Deskripsi Masalah

Restoran "Rasa Nusantara" memerlukan program untuk mencetak nota pembayaran pelanggan. Program menerima data empat pesanan: nama menu, harga satuan, dan jumlah pesan. Selanjutnya program menghitung subtotal, menambahkan pajak restoran 10 persen, dan menambahkan biaya layanan tetap Rp 20.000. Nota akan dicetak dalam format yang rapi.

9.2 Aturan Perhitungan

Komponen Rumus
Subtotal per itemHarga satuan × jumlah
Subtotal totalJumlah semua subtotal
Pajak10 persen dari subtotal total
Biaya layananTetap Rp 20.000
Total bayarSubtotal + pajak + biaya layanan

9.3 Flowchart Studi Kasus

flowchart TD
    A(["Mulai"]) --> B[/"Baca 4 pesanan:
nama, harga, jumlah"/] B --> C["subtotal1 = harga1 * jumlah1"] C --> D["subtotal2 = harga2 * jumlah2"] D --> E["subtotal3 = harga3 * jumlah3"] E --> F["subtotal4 = harga4 * jumlah4"] F --> G["totalSubtotal = jumlah semua subtotal"] G --> H["pajak = totalSubtotal * 0.10"] H --> I["biayaLayanan = 20000"] I --> J["totalBayar = totalSubtotal + pajak + biayaLayanan"] J --> K[/"Cetak nota terformat"/] K --> L(["Selesai"])

Gambar 9.1 - Flowchart perhitungan nota restoran

9.4 Pseudocode Studi Kasus

PROGRAM NotaRestoran
{ Mencetak nota pembayaran restoran dengan format rapi }

KONSTANTA
  PAJAK_PERSEN  = 0.10
  BIAYA_LAYANAN = 20000
  NAMA_RESTORAN = "Rasa Nusantara"
  GARIS_GANDA   = "================================================"
  GARIS_TUNGGAL = "------------------------------------------------"

DEKLARASI
  menu1, menu2, menu3, menu4       : string
  harga1, harga2, harga3, harga4   : currency
  jumlah1, jumlah2, jumlah3, jumlah4 : integer
  subtotal1, subtotal2, subtotal3, subtotal4 : currency
  totalSubtotal : currency
  pajak         : currency
  totalBayar    : currency

ALGORITMA
  write("Menu 1        : ")
  read(menu1)
  write("Harga 1       : ")
  read(harga1)
  write("Jumlah 1      : ")
  read(jumlah1)

  write("Menu 2        : ")
  read(menu2)
  write("Harga 2       : ")
  read(harga2)
  write("Jumlah 2      : ")
  read(jumlah2)

  write("Menu 3        : ")
  read(menu3)
  write("Harga 3       : ")
  read(harga3)
  write("Jumlah 3      : ")
  read(jumlah3)

  write("Menu 4        : ")
  read(menu4)
  write("Harga 4       : ")
  read(harga4)
  write("Jumlah 4      : ")
  read(jumlah4)

  subtotal1 <- harga1 * jumlah1
  subtotal2 <- harga2 * jumlah2
  subtotal3 <- harga3 * jumlah3
  subtotal4 <- harga4 * jumlah4

  totalSubtotal <- subtotal1 + subtotal2 + subtotal3 + subtotal4
  pajak         <- totalSubtotal * PAJAK_PERSEN
  totalBayar    <- totalSubtotal + pajak + BIAYA_LAYANAN

  write(GARIS_GANDA)
  write(NAMA_RESTORAN terpusat)
  write("NOTA PEMBAYARAN")
  write(GARIS_GANDA)
  write("No  Menu              Harga    Jml   Subtotal")
  write(GARIS_TUNGGAL)
  write("1   ", menu1 rata kiri 15, harga1 8 des2, jumlah1 3, subtotal1 10 des2)
  write("2   ", menu2 rata kiri 15, harga2 8 des2, jumlah2 3, subtotal2 10 des2)
  write("3   ", menu3 rata kiri 15, harga3 8 des2, jumlah3 3, subtotal3 10 des2)
  write("4   ", menu4 rata kiri 15, harga4 8 des2, jumlah4 3, subtotal4 10 des2)
  write(GARIS_TUNGGAL)
  write("Subtotal".PadLeft(40), totalSubtotal 18 des2)
  write("Pajak 10%".PadLeft(40), pajak 18 des2)
  write("Biaya Layanan".PadLeft(40), BIAYA_LAYANAN 18 des2)
  write(GARIS_TUNGGAL)
  write("TOTAL BAYAR".PadLeft(40), totalBayar 18 des2)
  write(GARIS_GANDA)
END

9.5 Implementasi dalam Pascal

nota_restoran.pas Pascal
program NotaRestoran;
{ Studi Kasus Modul 5 - Pencetakan nota pembayaran restoran }

uses
  strutils;

const
  PAJAK_PERSEN  = 0.10;
  BIAYA_LAYANAN = 20000;
  NAMA_RESTORAN = 'Rasa Nusantara';
  GARIS_GANDA   = '================================================';
  GARIS_TUNGGAL = '------------------------------------------------';

var
  menu1, menu2, menu3, menu4: string;
  harga1, harga2, harga3, harga4: currency;
  jumlah1, jumlah2, jumlah3, jumlah4: integer;
  subtotal1, subtotal2, subtotal3, subtotal4: currency;
  totalSubtotal, pajak, totalBayar: currency;

begin
  writeln('Masukkan data pesanan');
  writeln(GARIS_TUNGGAL);
  writeln;

  write('Menu 1   : ');  readln(menu1);
  write('Harga 1  : ');  readln(harga1);
  write('Jumlah 1 : ');  readln(jumlah1);
  writeln;

  write('Menu 2   : ');  readln(menu2);
  write('Harga 2  : ');  readln(harga2);
  write('Jumlah 2 : ');  readln(jumlah2);
  writeln;

  write('Menu 3   : ');  readln(menu3);
  write('Harga 3  : ');  readln(harga3);
  write('Jumlah 3 : ');  readln(jumlah3);
  writeln;

  write('Menu 4   : ');  readln(menu4);
  write('Harga 4  : ');  readln(harga4);
  write('Jumlah 4 : ');  readln(jumlah4);

  subtotal1 := harga1 * jumlah1;
  subtotal2 := harga2 * jumlah2;
  subtotal3 := harga3 * jumlah3;
  subtotal4 := harga4 * jumlah4;

  totalSubtotal := subtotal1 + subtotal2 + subtotal3 + subtotal4;
  pajak := totalSubtotal * PAJAK_PERSEN;
  totalBayar := totalSubtotal + pajak + BIAYA_LAYANAN;

  writeln;
  writeln(GARIS_GANDA);
  writeln(NAMA_RESTORAN.Center(48));
  writeln('NOTA PEMBAYARAN'.Center(48));
  writeln(GARIS_GANDA);
  writeln('No  Menu           Harga    Jml    Subtotal');
  writeln(GARIS_TUNGGAL);

  writeln(1:2, '  ', menu1:-(12), ' ', harga1:8:0, jumlah1:6, subtotal1:12:2);
  writeln(2:2, '  ', menu2:-(12), ' ', harga2:8:0, jumlah2:6, subtotal2:12:2);
  writeln(3:2, '  ', menu3:-(12), ' ', harga3:8:0, jumlah3:6, subtotal3:12:2);
  writeln(4:2, '  ', menu4:-(12), ' ', harga4:8:0, jumlah4:6, subtotal4:12:2);

  writeln(GARIS_TUNGGAL);
  writeln('Subtotal'.PadLeft(34), totalSubtotal:14:2);
  writeln('Pajak 10%'.PadLeft(34), pajak:14:2);
  writeln('Biaya Layanan'.PadLeft(34), BIAYA_LAYANAN:14:2);
  writeln(GARIS_TUNGGAL);
  writeln('TOTAL BAYAR'.PadLeft(34), totalBayar:14:2);
  writeln(GARIS_GANDA);
end.

9.6 Contoh Keluaran

Masukkan data pesanan
------------------------------------------------

Menu 1   : Nasi Goreng Spesial
Harga 1  : 45000
Jumlah 1 : 2

Menu 2   : Sate Ayam Madura
Harga 2  : 35000
Jumlah 2 : 3

Menu 3   : Es Teh Manis
Harga 3  : 8000
Jumlah 3 : 4

Menu 4   : Kerupuk Udang
Harga 4  : 5000
Jumlah 4 : 2

================================================
                Rasa Nusantara
               NOTA PEMBAYARAN
================================================
No  Menu           Harga    Jml    Subtotal
------------------------------------------------
 1  Nasi Goreng    45000      2     90000.00
 2  Sate Ayam      35000      3    105000.00
 3  Es Teh Manis    8000      4     32000.00
 4  Kerupuk Udang   5000      2     10000.00
------------------------------------------------
                          Subtotal    237000.00
                         Pajak 10%     23700.00
                     Biaya Layanan     20000.00
------------------------------------------------
                         TOTAL BAYAR   280700.00
================================================

9.7 Pembahasan

Beberapa keputusan perancangan penting pada program ini.

  1. Konstanta untuk pajak dan biaya layanan. Nilai-nilai ini adalah parameter bisnis yang mungkin berubah. Dengan konstanta, perubahan cukup di satu tempat.
  2. Fungsi Center dan PadLeft. Keduanya berasal dari unit strutils. Center memusatkan teks dalam lebar tertentu, PadLeft menambahkan padding di kiri. Keduanya membantu membuat keluaran terlihat rapi.
  3. Format bertingkat pada baris data. Baris writeln(1:2, ' ', menu1:-(12), ...) memiliki enam argumen yang digabungkan: nomor urut, dua spasi, nama menu rata kiri, harga, jumlah, dan subtotal. Setiap argumen memiliki lebar yang konsisten dengan header tabel.
  4. Penggunaan currency. Semua nilai uang memakai currency untuk memastikan presisi eksak hingga 4 angka desimal.
  5. Baris kosong pemisah. Menyisipkan writeln; setelah setiap blok masukan memberi jeda visual yang memudahkan pengguna membaca.

9.8 Pengembangan Selanjutnya

Modul Pengembangan
Modul 6Menambahkan diskon bila total melebihi ambang tertentu
Modul 8Memproses jumlah pesanan yang tidak terbatas dengan perulangan
Modul 11Memindahkan blok cetak nota ke prosedur terpisah
Modul 16Menyimpan pesanan dalam array
Modul 20Mengelompokkan data pesanan dalam record
Modul 25Menyimpan nota ke berkas untuk arsip
10

Rangkuman

Poin-poin kunci yang perlu diingat dari Modul 5

  1. Empat prosedur I/O dasar adalah read, readln, write, dan writeln.
  2. writeln menambahkan baris baru setelah menampilkan, write tidak.
  3. readln membaca sampai akhir baris dan membuang pemisahnya, read berhenti pada pemisah pertama dan meninggalkannya di stream.
  4. Untuk masukan dari keyboard, hampir selalu gunakan readln untuk menghindari masalah baris baru yang tertinggal.
  5. Format :lebar menentukan lebar field minimum. Nilai numerik rata kanan, string rata kiri (default).
  6. Format :lebar:desimal untuk real: lebar field dan jumlah angka desimal. Lebar 0 berarti lebar minimum.
  7. Lebar string negatif (:-(n)) membuat string rata kiri pada lebar n. Fitur ini khas Free Pascal.
  8. Karakter escape ditulis dengan #kode, misalnya #9 untuk tab dan #10 untuk newline.
  9. Unit crt menyediakan ClrScr, GotoXY, TextColor, ReadKey, dan Delay.
  10. ReadKey membaca satu tombol tanpa menampilkannya. Umpan balik visual harus diberikan secara manual.
  11. Unit strutils menyediakan PadLeft, PadRight, dan Center untuk perataan teks.
  12. Tabel keluaran rapi dibuat dengan kombinasi lebar field yang konsisten antara header dan data.
Sebelum Melanjutkan

Pastikan Anda sudah dapat membuat program yang menerima masukan dengan aman dan menampilkan keluaran terformat. Cobalah membuat tabel keluaran sederhana tanpa melihat contoh. Modul 6 akan masuk ke percabangan, di mana kemampuan input/output yang baik akan sangat membantu.

11

Referensi

Sumber rujukan yang digunakan dalam penyusunan modul ini

Buku Teks

  1. Jensen, K., & Wirth, N. (1991). Pascal User Manual and Report (4th ed.). Springer-Verlag. Bab 8 membahas prosedur input/output standar.
  2. Cantu, M. (2020). Object Pascal Handbook. Marco Cantu. Bab tentang input/output dan pemformatan pada Free Pascal dan Delphi.
  3. Cooper, D., & Clancy, M. (1982). Oh! Pascal! W. W. Norton & Company. Bab tentang interaksi dengan pengguna.
  4. Grogono, P. (1995). Programming with Pascal. Addison-Wesley. Bab 5 membahas prosedur I/O standar.

Dokumentasi Resmi

  1. Free Pascal Team. Free Pascal Reference Guide. Bab tentang prosedur standar read, readln, write, dan writeln. Tersedia di freepascal.org/docs.html.
  2. Free Pascal Team. Free Pascal Run-Time Library Reference. Bab tentang unit crt dan strutils.
  3. Lazarus IDE Documentation. Panduan penggunaan komponen I/O pada antarmuka grafis.

Artikel dan Sumber Daring

  1. IEEE Computer Society. (1990). IEEE Standard for Pascal (IEEE Std 770-1983). Bab tentang prosedur I/O standar.
  2. Free Pascal Community Forum. Diskusi tentang perbedaan perilaku read dan readln di berbagai platform.
  3. Stack Overflow. Pertanyaan-pertanyaan populer tentang masalah baris baru yang tertinggal di Pascal.