Terminalden çalıştırdığınız her programa argüman verilebilir: gcc -Wall hello.c -o hello dört tane geçirir. Kendi C programlarınız kendilerininkini main üzerindeki iki parametreden okur ve mekanizmanın tamamı budur - kütüphane çağrısı yok, kurulum yok.
İmza
Şimdiye kadar bu belgelerdeki her örnek int main(void) kullandı. Diğer standart biçim komut satırını alır:
int main(int argc, char *argv[]) {
/* ... */
}
argc("argument count"), program adı dahil kaç argüman olduğudur.argv("argument vector"), bir metin dizisidir.char *argv[], "char'a göstericilerden oluşan dizi" demektir ki bu bir C metinleri dizisidir.
char **argv da aynı sıklıkta göreceğiniz eşdeğer bir yazımdır; dizi parametreleri göstericiye dönüşür, dolayısıyla ikisi aynı şeyi bildirir.
Argüman vermek için editörün Args panelini kullanın (her alan bir argümandır), sonra Çalıştır'a basın. Üç alan deneyin: merhaba, dunya, 42.
Anatomi
./greet Ada Lovelace çalıştırmak şunu üretir:
| İndeks | Değer | |
|---|---|---|
argv[0] | "./greet" | çağrıldığı hâliyle program adı |
argv[1] | "Ada" | ilk gerçek argüman |
argv[2] | "Lovelace" | ikinci gerçek argüman |
argv[3] | NULL | sonlandırıcı |
argc | 3 | argv[0] dahil sayı |
Akılda tutulmaya değer dört olgu:
argcpratikte en az 1'dir, çünküargv[0]program adıdır. Gerçek argümanlar 1. indeksten başlar; onlar üzerindeki döngülerini = 1'den başlamasının sebebi budur.- Her şey bir metindir.
./prog 42size iki karakterden oluşan"42"'yi verir, asla 42 sayısını değil. Dönüştürmek sizin işiniz. argv[argc],NULL'dur. Standart bunu garanti eder, dolayısıyla isterseniz diziyiargcolmadan dolaşabilirsiniz:for (char **p = argv + 1; *p != NULL; p++).- Kelimeleri kabuk böler, programınız değil.
./prog "Ada Lovelace"tek bir argümandır; tırnaklar kabuk tarafından tüketilir veargv'ye hiç ulaşmaz.
Okumadan Önce Kontrol Etmek
Geçirilmemiş bir argüman boş bir metin değildir - dokunmaya hakkınız olmayan bellektir. Her zaman önce argc'yi doğrulayın:
O minik programda iki gelenek var, ikisi de Unix araçlarında standart:
- Kullanım mesajı
stdout'a değilstderr'e gider, böylece bir yere borulanan çıktıyı kirletmez. main'den sıfırdan farklı bir dönüş, programı çalıştıran her neyse ona başarısızlığı bildirir.0başarı demektir; başka her şey bir şeylerin ters gittiğini. Kabuk betikleri bunu kontrol eder.
Sabit yazılmış bir isim yerine argv[0] yazdırmak, program yeniden adlandırılmış ya da farklı bir yoldan erişilmiş olsa bile mesajın kullanıcının programı çağırma biçimiyle eşleşmesi demektir.
Sayısal Argümanları Dönüştürmek
argv[1] metindir. Aritmetik yapmak için onu dönüştürmeniz gerekir ve kullanılacak fonksiyon <stdlib.h>'deki strtol'dür:
10, 20 ve 30 değerlerini üç ayrı Args alanı olarak ekleyin, sonra hata yolunu görmek için birini muz ile değiştirin.
strtol'ün üçüncü parametresi tabandır: ondalık için 10, on altılık için 16 ya da bir 0x veya baştaki sıfır önekinden otomatik algılamak için 0. İkincisi, tüketmediği ilk karaktere giden bir göstericinin nereye saklanacağıdır ve hata denetimini mümkün kılan da budur:
end == text, hiçbir şey ayrıştırmadı demektir - argüman bir sayıyla başlamadı.*end != '\0', sayıdan sonra artık metin vardı demektir, dolayısıyla"12abc"sessizce 12 olmak yerine reddedilir.errno == ERANGE, değerinlong'u taşırdığı anlamına gelir.
Daha kısa olan ve bunların hiçbirini bildiremeyen atoi ile karşılaştırın:
int n = atoi(argv[1]); /* "muz" -> 0, "0" -> 0, taşma -> tanımsız */
atoi geçersiz girdi için 0 döndürür ki bu gerçek bir sıfırdan ayırt edilemez. Girdi programınızın dışından geldiğinde strtol (ve kayan nokta için strtod) kullanın. Daha fazlası metin dönüşümü sayfasında.
Küçük Bir Hesap Makinesi
Hepsini bir araya getirelim - bir sayı, bir operatör ve bir sayı alan bir program:
12 + 30, sonra 7 x 6, sonra 5 / 0 deneyin.
op == "+" yerine strcmp(op, "+") == 0 olduğuna dikkat edin. char * değerlerini == ile karşılaştırmak içerikleri değil adresleri karşılaştırır ve aynı metin için bile yanlış olurdu. Bkz. metin fonksiyonları.
* yerine x gerçek hayattan bir ayrıntıdır: çoğu kabuk, programınız daha çalışmadan önce çıplak bir *'ı geçerli dizindeki dosya listesine genişletir. Tırnak içine almak ('*') da işe yarar, ama kabuğun yok saydığı bir karakter seçmek daha dostçadır.
Bayrakları Ayrıştırmak
Seçenekler geleneksel olarak - ile başlar. Basit, elle yazılmış bir döngü yaygın durumları halleder:
Dört Args alanıyla deneyin: -v, -n, 3, merhaba.
argv[++i]'den önceki i + 1 >= argc kontrolü önemli satırdır: değer bekleyen bir seçenek, değerin gerçekten orada olduğunu doğrulamalıdır, yoksa son argüman olarak -n dizinin sonunun ötesini okur. Gerçek Unix sistemlerinde <unistd.h>'deki getopt bunların hepsini sizin için yapar, -vn3 gibi birleştirilmiş kısa seçenekler dahil; bir programın ikiden üçten fazla bayrağı olduğunda ona uzanmaya değer.
Tarayıcı Editöründe Argümanlar
Bu sayfadaki editör blokları sizin için derlenip çalıştırılır ve Args paneli, bir terminalde program adından sonra yazacaklarınızı yazdığınız yerdir. Add arg ile eklediğiniz her alan, tam olarak argv'de tek bir kayıt olur - arada bir kabuk yoktur, dolayısıyla hiçbir şey boşluklardan bölünmez ve tırnak gerekmez: merhaba dunya içeren bir alan, tek bir merhaba dunya argümanı olarak gelir. -n 3 merhaba geçirmek için üç alan ekleyin. Paneli boş bırakmak argc == 1 verir - argc < 2 korumasının ilk çalıştırmada devreye girmesinin ve onu yazmaya değmesinin sebebi budur.
Sık Yapılan Hatalar
argc'yi kontrol etmedenargv[1]'i okumak. Hiç argüman geçirilmediğinde tanımsız davranıştır - ve bu alandaki en yaygın çökme.- Döngüyü
i = 0'dan başlatmak. Bu, program adını veriymiş gibi işler. argv[1]'i sayı olarak görmek. Siz dönüştürene kadar metindir.- Kullanıcı girdisinde
atoikullanmak. Kötü bir argümanı sıfırdan ayırt etmenin yolu yoktur. - Metinleri
==ile karşılaştırmak.strcmpkullanın. argvmetinlerinin içine yazmak. Onları değiştirmeye standart izin verir ama alan sınırlı ve platforma bağlıdır; bir şeyi değiştirmeniz gerekiyorsa kendi tamponunuza kopyalayın.
Sıkça Sorulan Sorular
C'de argc ve argv nedir?
Bunlar int main(int argc, char *argv[])'nin iki parametresidir. argc, program adı dahil komut satırı argümanlarının sayısıdır; argv ise bu argümanların metin olarak dizisidir. argv[0] program adıdır, argv[1] ilk gerçek argümandır ve argv[argc] her zaman NULL'dur.
Bir C programına nasıl argüman geçilir?
Terminalde çalıştırılabilir dosyanın adından sonra yazın: ./program merhaba 42. Bu argc == 3 verir; argv[1] "merhaba" metni, argv[2] ise "42" metnidir. Bu sayfadaki editörde argümanlar terminal yerine Args paneline yazılır.
C'de bir komut satırı argümanı int'e nasıl dönüştürülür?
strtol kullanın: char *end; long n = strtol(argv[1], &end, 10); ardından end'in hâlâ başlangıcı göstermediğini (hiçbir şey ayrıştırılmadı) ve *end'in '\0' olduğunu (artık çöp yok) kontrol edin. atoi daha kısadır ama hem "0" hem "muz" için 0 döndürür, dolayısıyla hata bildiremez.
C'de argv[0] nedir?
Programın çağrıldığı isim - genellikle ./program ya da tam yol. Kullanım mesajlarında (fprintf(stderr, "kullanim: %s DOSYA\n", argv[0])) işe yarar, böylece mesaj kullanıcının onu gerçekten nasıl çağırdığıyla eşleşir. Sıra dışı durumlarda boş bir metin olabilir, o yüzden var olduğunu varsaymayın.