Program C yang dirakit sejauh ini menerima masukan dari dalam kode atau dari aliran standar. Bahasa C juga menyediakan jalur masukan yang paling umum dipakai oleh perangkat lunak terminal, yaitu argumen yang diketik bersama nama program ketika program dijalankan. Topik ini membahas parameter argc dan argv, cara menelusuri argumennya, serta pembangunan alat command line sederhana bernama statistik yang menerima deret angka dan menghitung ringkasannya.
Parameter argc dan argv#
Fungsi main dapat dideklarasikan dengan dua parameter yang diisi oleh lingkungan eksekusi saat program dijalankan. Parameter pertama, lazim dinamai argc (argument count), berupa bilangan bulat yang menyatakan banyaknya argumen termasuk nama program itu sendiri, sehingga nilai terkecilnya adalah 1. Parameter kedua, lazim dinamai argv (argument vector), berupa array pointer ke string yang berisi teks tiap argumen.
// tidak-dijalankan
int main(int argc, char *argv[]) {
/* argc : banyak argumen, termasuk nama program */
/* argv[0]: nama program sebagaimana ia dipanggil */
/* argv[1]: argumen pertama dari pengguna */
return 0;
}Posisi argv[0] menyimpan nama program sebagaimana dipanggil, bukan argumen pengguna, sehingga argumen pengguna dimulai dari argv[1]. Di akhir array, argv[argc] selalu berisi NULL sebagai penanda habis. Program berikut mencetak seluruh isinya.
// tidak-dijalankan
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("argc = %d\n", argc);
for (int i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}# mengompilasi program pencetak argumen
gcc cetak-argv.c -o cetak-argv
# menjalankannya dengan dua argumen
./cetak-argv satu duaargc = 3
argv[0] = ./cetak-argv
argv[1] = satu
argv[2] = duaYang memecah baris perintah menjadi argumen-argumen tersebut adalah shell. Shell membagi masukan pada setiap spasi sebelum meneruskannya ke program. Apabila sebuah argumen memang harus mengandung spasi, argumen itu perlu diapit tanda kutip, misalnya ./cetak-argv "satu dua" yang diterima program sebagai satu argumen utuh. Tanpa argumen apa pun, program yang sama mencetak argc = 1 dan hanya menampilkan argv[0].
Meskipun berasal dari luar program, teks-teks pada argv sah untuk diubah selama program berjalan, misalnya untuk menormalkan huruf besar atau kecil sebelum diproses. Array argv itu sendiri merupakan deretan pointer yang menunjuk string-string terpisah di memori, sehingga panjang tiap argumen tidak perlu seragam. Seluruh penyiapan ini selesai sebelum baris pertama main dijalankan, sehingga argumen dapat dipakai sejak awal program tanpa persiapan apa pun.
Menelusuri argumen dengan perulangan#
Sebagian besar alat command line menelusuri argumen pengguna dengan perulangan yang dimulai dari indeks 1, karena indeks 0 adalah nama program. Bentuk perulangannya mengikuti pola di bawah ini.
// tidak-dijalankan
for (int i = 1; i < argc; i++) {
printf("Argumen %d: %s\n", i, argv[i]);
}Penanda NULL pada argv[argc] memberikan alternatif kedua yang tidak memerlukan argc sama sekali, yaitu perulangan yang berhenti ketika elemennya NULL. Kedua bentuk itu setara untuk kasus biasa. Yang penting adalah konsistensi: indeks awal 1, batas atas argc, dan kesadaran bahwa setiap elemen berupa string, bukan angka. Konversi dari teks ke bilangan harus dilakukan secara eksplisit sebelum argumen dipakai dalam perhitungan.
Argumen yang diawali tanda hubung seperti -v atau --ringkas lazim diperlakukan sebagai opsi, sedangkan sisanya berupa data posisi yang diolah. Pembedaan keduanya hanya kesepakatan, karena bahasa C tidak menyediakan fungsi parsing opsi di dalam standarnya. Untuk alat kecil, pemeriksaan sederhana dengan perbandingan strcmp sudah cukup. Alat yang opsinnya terus bertambah biasanya beralih ke kerangka parsing seperti getopt yang tersedia pada banyak sistem POSIX.
Membangun alat command line: statistik nilai#
Alat yang dibangun pada bagian ini menerima deret angka melalui argumen, lalu melaporkan banyaknya nilai, total, dan rata-ratanya. Apabila dipanggil tanpa argumen, alat ini menampilkan petunjuk pemakaian alih-alih langsung gagal, kebiasaan yang lazim pada alat command line.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Pemakaian: ./statistik angka1 angka2 ...\n");
printf("Contoh : ./statistik 80 75 90\n");
return 0;
}
int total = 0;
for (int i = 1; i < argc; i++) {
total += atoi(argv[i]);
}
printf("Banyak nilai : %d\n", argc - 1);
printf("Total : %d\n", total);
printf("Rata-rata : %.2f\n", (double) total / (argc - 1));
return 0;
}Pemakaian: ./statistik angka1 angka2 ...
Contoh : ./statistik 80 75 90Fungsi atoi mengubah teks argumen menjadi bilangan bulat, dan pengecoran (double) pada pembagian menjaga agar rata-rata tidak dipotong menjadi bilangan bulat. Alat ini dijalankan dengan argumen nyata melalui shell.
# mengompilasi alat statistik
gcc statistik.c -o statistik
# menghitung ringkasan tiga nilai ujian
./statistik 80 75 90Banyak nilai : 3
Total : 245
Rata-rata : 81.67Struktur alat semacam ini mampu menerima sejumlah argumen apa pun tanpa diubah, karena perulangannya mengikuti nilai argc. Konversi atoi dipilih karena singkat, tetapi konversi ini tidak melaporkan error apa pun, sedangkan parsing yang lebih aman menggunakan keluarga strtol dibahas pada topik stdlib.h Lanjutan dalam modul ini.
Apabila salah satu argumen bukan angka, atoi menganggapnya 0 dan perhitungan terus berjalan tanpa peringatan, misalnya ./statistik 80 tujuh 90 menghasilkan total 170. Perilaku itu dapat diterima untuk alat pribadi yang sederhana, tetapi menjadi sumber salah hitung yang sulit dilacak pada alat yang dipakai orang lain. Verifikasi setiap argumen sebelum dihitung, atau gunakan konversi yang dapat memeriksa errornya.
Rancangan alat command line yang sehat menaruh petunjuk pemakaian pada saat argumen tidak lengkap, karena petunjuk itu terbaca tanpa membuka dokumentasi. Syarat argc < 2 memang sederhana, tetapi sudah menutup kasus pemanggilan kosong sekalipun alat ini belum mendukung opsi bernilai. Pengembangan lanjutannya, misalnya opsi pemilihan laporan atau keluaran berformat, tetap berada pada pola yang sama, yaitu periksa, konversi, hitung, lalu laporkan.
Kesalahan umum#
- Membaca
argv[1]tanpa memeriksaargc. Program yang dipanggil tanpa argumen memilikiargcbernilai 1, sehinggaargv[1]berisi NULL. Memakai NULL itu sebagai string merupakan perilaku tak terdefinisi yang sering berujung pada program yang berhenti mendadak. Periksaargcterlebih dahulu sebelum mengakses indeks mana pun. - Mengira
argv[0]selalu berbentuk nama pendek. Isiargv[0]mengikuti cara pemanggilan, misalnya./statistik,/usr/bin/statistik, atau teks lain pada pemanggilan tertentu. Logika program tidak boleh bergantung pada bentuk pastinya. - Mengoper teks angka langsung ke perhitungan. Elemen
argvberupa string, sehinggaargv[1] + argv[2]menjumlahkan dua alamat memori, bukan dua nilai. Konversikan setiap argumen denganatoiataustrtolsebelum dihitung. - Mengabaikan banyaknya argumen yang tidak sesuai rancangan. Alat yang menuntut persis tiga angka tetap berjalan apabila diberi lima argumen, karena
argctidak pernah divalidasi lebih jauh. Periksa jumlah yang diharapkan secara eksplisit, misalnya denganif (argc != 4), apabila format pemanggilannya memang tetap.
Ringkasan#
argcmenyatakan banyak argumen termasuk nama program, sedangkanargvmenyimpan teks tiap argumen sebagai array pointer ke string.- Argumen pengguna dimulai pada
argv[1], danargv[argc]selalu berisi NULL sebagai penanda habis. - Alat command line memeriksa
argclebih dahulu, menampilkan petunjuk pemakaian bila argumen kurang, lalu mengonversi tiap argumen sebelum dipakai dalam perhitungan. - Shell memecah baris perintah pada setiap spasi, sehingga teks yang mengandung spasi perlu diapit tanda kutip.
Referensi#
- The main function — cppreference.com
— Kontrak parameter
argcdanargv, termasuk jaminanargv[argc]berupa NULL. - exec(3) — man7.org
— Cara lingkungan eksekusi menyusun
argvketika program dijalankan.