Sayfalar

Menü

12 Nisan 2021 Pazartesi

Komut Satırı Argümanları C programlama

 Bir program çalıştırıldığı zaman, programın çalışmasını yönlendirecek ya da değiştirecek

bazı parametreler, çalışacak programa gönderilmek istenebilir. Programa gönderilecek bir
parametre örneğin bir dosya ismi olabileceği gibi, programın değişik biçimlerde
çalışmasını sağlayacak bir seçenek de olabilir. UNIX işletim sistemindeki ls komutunu
düşünelim. Eğer ls programı
ls
yazarak çalıştırılırsa, bulunulan dizin içindeki dosyaların isimleri listelenir. Ama ls yerine
ls -l
yazılarak program çalıştırılırsa bu kez yalnızca dosya isimleri değil, dizindeki dosyaların
büyüklüğünü, dosyaların sahiplerini, yaratılma tarih ve zamanlarını vs. gösteren daha
ayrıntılı bir liste ekranda görüntülenir. ls programı yine
ls -l sample.c
yazarak çalıştırılırsa, yalnızca sample.c dosyasına ilişkin bilgiler görüntülenir. İşte bir
programı çalıştırırken program isminin yanına yazılan diğer parametrelere komut satırı
argümanları (command line arguments) denir.
Komut satırı argümanları yalnızca işletim sistemi komutları için geçerli değildir. Tüm
programlar için komut satırı argümanları kullanılabilir. Komut satırı argümanlarına C dili
standartlarında program parametreleri (program parameters) denir.
C programlarının çalışmaya başladığı main işlevi de, isteğe bağlı olarak iki parametre
değişkenine sahip olabilir. Bu parametre değişkenleri geleneksel olarak argc ve argv
olarak isimlendirilir.
int main(int argc, char *argv[])
{
/***/
}
argc "argument count" sözcüklerinden kısaltılmıştır. Komut satırı argümanlarının sayısını
gösterir. Bu sayıya programın ismi de dahildir. argv ise "argument vector" sözcüklerinden
kısaltılmıştır. argv, dizgeler şeklinde saklanan komut satırı argümanlarını gösteren, char
türden bir gösterici dizisinin adresini alan göstericidir. Yani argv göstericisinin gösterdiği
yerde bir gösterici dizisi vardır. Bu gösterici dizisinin her elemanı, komut satırı argümanı
olan yazıları tutar. Bu durumda argv[0] göstericisi programın ismi olan yazının başlangıç
adresini tutar. argv[1]'den argv[argc - 1] e kadar olan göstericiler ise program ismini
izleyen diğer komut satırı argümanı olan yazıların başlangıç adreslerini tutar.
argv[argc] göstericisi ise NULL adresi değerine sahiptir.
Yukarıdaki örnekte kullanıcı ls programını
ls -l sample.c
şeklinde çalıştırdığında
argc, 3 değerini alır.
argv[0], program ismini gösterir.
argv[0] = "ls";
argv[1] program ismini izleyen birinci argümanı gösterir.
argv[1] = "-l";
argv[2] program ismini izleyen ikinci argümanı gösterir.
argv[2] = "sample.c";
argv[argc] yani argv[3] ise NULL adresini gösterir.
Bir işlevin, göstericiyi gösteren gösterici (pointer to pointer) parametresinin iki ayrı
biçimde tanımlanabileceğini anımsayın:
void func(char **ptr);
void foo(char *ptr[]);
Her iki işlevin de parametre değişkeni char türden göstericiyi gösteren bir göstericidir. Bu
durumda, komut satırı argümanlarını işleyecek bir main işlevinin de göstericiyi gösteren
gösterici olan argv parametresi, iki farklı biçimde tanımlanabilir:
int main(int argc, char **argv)
{
/***/
}
int main(int argc, char **argv)
{
/***/
}
Komut satırı argümanları boşluklarla birbirinden ayrılmış olmalıdır. Yukarıdaki örnekte
program
ls -lsample.c
biçiminde çalıştırılırsa
argc, 2 değerine sahip olurdu.
Komut satırı argümanları, işletim sistemi tarafından komut satırından alınarak derleyicinin
ürettiği giriş kodu yardımıyla main işlevine gönderilir.
Aşağıda komut satırı argümanlarını ekrana basan örnek bir program görüyorsunuz:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for (i = 0; i < argc; ++i)
printf("argv[%d] : %s\n", i, argv[i]);
return 0;
}
main işlevinde yer alan döngü deyimi aşağıdaki biçimde de yazılabilirdi:
for (i = 0; argv[i] != NULL ; ++i)
printf("argv[%d] : %s\n", i, argv[i]);
Komut satırından çalıştırılan programlar genellikle, önce girilen argümanları yorumlar ve
sınar. Örneğin bir dosyanın kopyasını çıkarmak üzere, ismi kopyala olan bir programın,
komut satırından çalıştırılmak istendiğini düşünelim. Program, komut satırından
kopyalanacak dosyanın ismini ve yeni yaratılacak dosyanın ismini istesin:
kopyala deneme.c test.c
Program komut satırından yukarıdaki gibi çalıştırıldığında, ismi deneme.c olan bir
dosyanın ismi test.c olan bir kopyasını oluştursun. Bu durumda argc 3 degerini alır, değil
mi?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
/***/
if (argc != 3) {
printf("kullanim : <kopyala> <kaynak dosya ismi> <yeni dosya
ismi>\n");
exit(EXIT_FAILURE);
}
/***/
return 0;
}
Yukarıdaki main işlevinde, program 3 komut satırı argümanı verilerek çalıştırılmadıysa,
yani eksik ya da fazla argümanla çalıştırıldıysa, program bir hata iletisiyle sonlandırılıyor.
Komut satırından argümanlar doğru girilmediği zaman bir program sonlandırılmak
zorunda değildir. Dışarıdan doğru olarak girilemeyen argümanların bu kez, programın
çalışması durumunda programı kullanan kişi tarafından girilmesi istenebilir.
Aşağıdaki örneği inceleyin:
#include <stdio.h>
#include <string.h>
#define NAME_LEN 80
int main(int argc, char *argv[])
{
char source_name[NAME_LEN];
char dest_name[NAME_LEN];
if (argc != 3) {
printf("kaynak dosyanin ismini giriniz : ");
gets(source_name);
printf("kopya dosyanin ismini giriniz : ");
gets(dest_name);
}
else {
strcpy(source_name, argv[1]);
strcpy(dest_name, argv[2]);
}
/***/
return 0;
}
DOS işletim sisteminde olduğu gibi, bazı sistemlerde main işlevi üçüncü bir parametre
alabilir. Üçüncü parametre sistemin çevre değişkenlerine ilişkin bir karakter türünden
göstericiyi gösteren göstericidir.
int main(int argc, char *argv[], char *env[])
{
/***/
}
Aşağıdaki programda, komut satırından girilen sözcükler ters sırada ve tersten
yazdırılıyor:
#include <stdio.h>
int main(int argc, char **argv)
{
int k, i;
for (k = argc - 1; k > 0; --k) {
for (i = 0; argv[k][i] != '\0'; ++i)
;
for (i--; i >= 0; --i)
putchar(argv[k][i]);
putchar('\n');
}
return 0;
}
Aşağıda, komut satırından çalıştırılacak basit bir hesap makinesi programının kodu
veriliyor:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
char ch;
int op1, op2;
if (argc != 4) {
printf("usage : cal Op1 Operator Op2\n");
exit(EXIT_FAILURE);
}
op1 = atoi(argv[1]);
op2 = atoi(argv[3]);
ch = argv[2][0];
printf(" = ");
switch (ch) {
case '+' : printf("%d\n", op1 + op2); return 0;
case '-' : printf("%d\n", op1 - op2); return 0;
case '/' : printf("%lf\n", (double)op1 / op2); return 0;
case '*' : printf("%d\n", op1 * op2); return 0;
case '%' : printf("%lf\n", (double)op1 * op2 / 100); return 0;
case 'k' : printf("%lf\n", pow(op1, op2)); return 0;
default : printf("hatalı işleç\n");
}
return 0;
}
Aşağıdaki program, komut satırından gün, ay ve yıl değerleri girilen bir tarihin haftanın
hangi gününe geldiğini ekrana yazdırıyor:
#include <stdio.h>
#include <stdlib.h>
char *days[] = {"Pazar", "Pazartesi", "Sali", "Carsamba", "Persembe",
"Cuma", "Cumartesi"};
int day_of_week(int d, int m, int y)
{
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4,6, 2, 4};
y -= m < 3;
return (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7;
}
int main(int argc, char **argv)
{
int day, mon, year;
if (argc != 4) {
printf("gun ay ve yil degerini giriniz : ");
scanf("%d%d%d", &day, &mon, &year);
}
else {
day = atoi(argv[1]);
mon = atoi(argv[2]);
year = atoi(argv[3]);
}
printf("%s\n", days[day_of_week(day, mon, year)]);
return 0;
}

Hiç yorum yok:

Yorum Gönder

Her yorum bilgidir. Araştırmaya devam...