Setiap program yang kamu jalankan dari terminal bisa diberi argumen: gcc -Wall hello.c -o hello memberikan empat argumen. Program C buatanmu sendiri membaca argumennya lewat dua parameter pada main, dan hanya itu mekanismenya: tanpa pemanggilan library, tanpa persiapan apa pun.
Signature-nya
Sejauh ini setiap contoh di dokumentasi ini memakai int main(void). Bentuk standar lainnya menerima command line:
int main(int argc, char *argv[]) {
/* ... */
}
argc("argument count") adalah jumlah argumen, termasuk nama program.argv("argument vector") adalah array berisi string.char *argv[]berarti "array berisi pointer ke char", yaitu array berisi string C.
char **argv adalah penulisan setara yang sama seringnya kamu temui; parameter array berubah menjadi pointer, jadi keduanya mendeklarasikan hal yang sama.
Gunakan panel Argumen di editor untuk memberi argumen (setiap field adalah satu argumen), lalu klik Jalankan. Coba tiga field: hello, world, 42.
Anatominya
Menjalankan ./greet Ada Lovelace menghasilkan:
| Indeks | Nilai | |
|---|---|---|
argv[0] | "./greet" | nama program seperti saat dipanggil |
argv[1] | "Ada" | argumen sungguhan pertama |
argv[2] | "Lovelace" | argumen sungguhan kedua |
argv[3] | NULL | penanda akhir |
argc | 3 | jumlah termasuk argv[0] |
Empat fakta yang layak diingat:
argcpaling sedikit 1 dalam praktiknya, karenaargv[0]adalah nama program. Argumen sungguhan dimulai dari indeks 1, karena itulah perulangan untuk menelusurinya dimulai darii = 1.- Semuanya adalah string.
./prog 42memberimu"42", dua karakter itu, bukan angka 42. Mengonversinya adalah tugasmu. argv[argc]adalahNULL. Dijamin oleh standar, jadi kamu bisa menelusuri array tanpaargckalau mau:for (char **p = argv + 1; *p != NULL; p++).- Shell yang memecah kata, bukan programmu.
./prog "Ada Lovelace"adalah satu argumen; tanda kutipnya dipakai oleh shell dan tidak pernah sampai keargv.
Periksa Sebelum Membaca
Argumen yang tidak diberikan bukan string kosong, melainkan memori yang tidak boleh kamu sentuh. Selalu validasi argc lebih dulu:
Ada dua konvensi di program kecil itu, keduanya standar di seluruh tool Unix:
- Pesan penggunaan dikirim ke
stderr, bukanstdout, agar tidak mengotori output yang sedang di-pipe ke tempat lain. - Nilai kembalian bukan nol dari
mainmemberi tanda gagal ke apa pun yang menjalankan program.0berarti sukses; nilai lain berarti ada yang salah. Script shell memeriksanya.
Mencetak argv[0], bukan nama yang ditulis langsung, membuat pesannya sesuai dengan cara pengguna memanggil program, bahkan kalau program itu sudah diganti namanya atau dipanggil lewat path lain.
Mengonversi Argumen Angka
argv[1] adalah teks. Untuk melakukan aritmetika kamu harus mengonversinya, dan fungsi yang dipakai adalah strtol dari <stdlib.h>:
Tambahkan 10, 20, 30 sebagai tiga field Argumen, lalu ganti salah satunya dengan banana untuk melihat jalur error-nya.
Parameter ketiga strtol adalah basis: 10 untuk desimal, 16 untuk heksadesimal, atau 0 untuk mendeteksi otomatis dari awalan 0x atau nol di depan. Parameter kedua adalah tempat menyimpan pointer ke karakter pertama yang tidak ia pakai, dan itulah yang membuat pemeriksaan error bisa dilakukan:
end == textberarti tidak ada yang di-parse: argumennya tidak diawali angka.*end != '\0'berarti ada sisa teks setelah angka, sehingga"12abc"ditolak, bukan diam-diam menjadi 12.errno == ERANGEberarti nilainya melampaui bataslong.
Bandingkan dengan atoi, yang lebih pendek dan tidak bisa melaporkan semua itu:
int n = atoi(argv[1]); /* "banana" -> 0, "0" -> 0, overflow -> undefined */
atoi mengembalikan 0 untuk input yang tidak valid, yang tidak bisa dibedakan dari nol sungguhan. Gunakan strtol (dan strtod untuk floating point) setiap kali input berasal dari luar programmu. Penjelasan lebih lanjut ada di konversi string.
Kalkulator Kecil
Menggabungkan semuanya: program yang menerima angka, operator, dan angka:
Coba 12 + 30, lalu 7 x 6, lalu 5 / 0.
Perhatikan strcmp(op, "+") == 0, bukan op == "+". Membandingkan nilai char * dengan == membandingkan alamat, bukan isinya, dan hasilnya false bahkan untuk teks yang sama persis. Lihat fungsi string.
x sebagai pengganti * adalah detail dari dunia nyata: sebagian besar shell mengubah * yang berdiri sendiri menjadi daftar file di direktori saat ini sebelum programmu sempat berjalan. Memberinya tanda kutip ('*') juga berhasil, tetapi memilih karakter yang diabaikan shell lebih ramah.
Parsing Flag
Opsi biasanya diawali -. Perulangan sederhana buatan sendiri sudah menangani kasus-kasus umum:
Coba dengan empat field Argumen: -v, -n, 3, hello.
Pemeriksaan i + 1 >= argc sebelum argv[++i] adalah baris yang penting: opsi yang mengharapkan nilai harus memastikan nilainya benar-benar ada, atau -n sebagai argumen terakhir akan membaca melewati ujung array. Di sistem Unix sungguhan, getopt dari <unistd.h> melakukan semua ini untukmu, termasuk opsi pendek yang digabung seperti -vn3; layak dipakai begitu sebuah program punya lebih dari dua atau tiga flag.
Argumen di Editor Browser
Blok editor di halaman ini dikompilasi dan dijalankan untukmu, dan panel Argumen adalah tempat kamu memberi apa yang biasanya ditulis setelah nama program di terminal. Setiap field yang kamu tambahkan dengan Tambah argumen menjadi tepat satu entri di argv. Tidak ada shell di antaranya, jadi tidak ada yang dipecah berdasarkan spasi dan tidak perlu tanda kutip: field berisi hello world diterima sebagai satu argumen hello world. Untuk memberikan -n 3 hello, tambahkan tiga field. Panel yang dibiarkan kosong menghasilkan argc == 1. Karena itulah pengaman argc < 2 langsung aktif di run pertama, dan karena itu pula pengaman tersebut layak ditulis.
Kesalahan Umum
- Membaca
argv[1]tanpa memeriksaargc. Undefined behavior kalau tidak ada argumen yang diberikan, dan inilah crash yang paling sering terjadi di area ini. - Memulai perulangan dari
i = 0. Itu memproses nama program seolah-olah data. - Memperlakukan
argv[1]sebagai angka. Ia tetap teks sampai kamu mengonversinya. - Memakai
atoiuntuk input pengguna. Tidak ada cara membedakan argumen yang salah dari nol. - Membandingkan string dengan
==. Gunakanstrcmp. - Menulis ke dalam string
argv. Mengubahnya diizinkan oleh standar, tetapi ruangnya terbatas dan bergantung pada platform; salin ke buffer milikmu sendiri kalau perlu mengubah sesuatu.
Pertanyaan yang sering diajukan
Apa itu argc dan argv di C?
Keduanya adalah dua parameter dari int main(int argc, char *argv[]). argc adalah jumlah argumen command line termasuk nama program; argv adalah array berisi argumen-argumen itu sebagai string. argv[0] adalah nama program, argv[1] adalah argumen sungguhan pertama, dan argv[argc] selalu NULL.
Bagaimana cara memberi argumen ke program C?
Ketik argumen setelah nama file executable di terminal: ./program hello 42. Hasilnya argc == 3, dengan argv[1] berisi string "hello" dan argv[2] berisi string "42". Di editor halaman ini, argumen dimasukkan di panel Argumen, bukan di terminal.
Bagaimana cara mengonversi argumen command line menjadi int di C?
Gunakan strtol: char *end; long n = strtol(argv[1], &end, 10); lalu periksa bahwa end tidak masih menunjuk ke awal (tidak ada yang di-parse) dan bahwa *end adalah '\0' (tidak ada sisa karakter sampah). atoi lebih pendek, tetapi mengembalikan 0 baik untuk "0" maupun "banana", sehingga tidak bisa melaporkan error.
Apa itu argv[0] di C?
Nama yang dipakai saat program dipanggil, biasanya ./program atau path lengkapnya. Ini berguna di pesan penggunaan (fprintf(stderr, "usage: %s FILE\n", argv[0])) agar pesannya sesuai dengan cara pengguna benar-benar memanggil program. Dalam kasus yang tidak biasa isinya bisa berupa string kosong, jadi jangan menganggapnya pasti ada.