Menu

Argumen Command Line di C: argc, argv, dan Parsing yang Aman

Cara program C membaca command line-nya: anatomi argc dan argv, menelusuri argumen, isi argv[0], mengonversi angka dengan strtol alih-alih atoi, dan kalkulator kecil yang menggabungkan semuanya.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

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:

IndeksNilai
argv[0]"./greet"nama program seperti saat dipanggil
argv[1]"Ada"argumen sungguhan pertama
argv[2]"Lovelace"argumen sungguhan kedua
argv[3]NULLpenanda akhir
argc3jumlah termasuk argv[0]

Empat fakta yang layak diingat:

  • argc paling sedikit 1 dalam praktiknya, karena argv[0] adalah nama program. Argumen sungguhan dimulai dari indeks 1, karena itulah perulangan untuk menelusurinya dimulai dari i = 1.
  • Semuanya adalah string. ./prog 42 memberimu "42", dua karakter itu, bukan angka 42. Mengonversinya adalah tugasmu.
  • argv[argc] adalah NULL. Dijamin oleh standar, jadi kamu bisa menelusuri array tanpa argc kalau 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 ke argv.

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, bukan stdout, agar tidak mengotori output yang sedang di-pipe ke tempat lain.
  • Nilai kembalian bukan nol dari main memberi tanda gagal ke apa pun yang menjalankan program. 0 berarti 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 == text berarti 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 == ERANGE berarti nilainya melampaui batas long.

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 memeriksa argc. 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 atoi untuk input pengguna. Tidak ada cara membedakan argumen yang salah dari nol.
  • Membandingkan string dengan ==. Gunakan strcmp.
  • 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.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai