getopt.h ile Programa Ait Seçeneklerin Argv Üzerinden İşlenmesi

Açık Kaynak, Programlama, tutorial, ytulinux

* http://www.advancedlinuxprogramming.com/ *

Evet “Önce bir selam vereydin” şeklindeki itirazlarınızı duyabiliyorum. Bu kaynak çok iyi, bu yüzden yazının başına yıldızla işaretlenmiş şekilde yazıyorum. Eğer linux üzerinde programlama konusunda aşmak istiyorum diyorsanız bir kaç haftalık tüm programınızı iptal edip bu kitaba yoğunlaşın derim. (Ne oldu zor geldi değil mi ehuehuehu zaten ben de azar azar ilerlemeyi düşünüyorum)

Neyse, konumuz programlara ait argümanların işlenmesi. Tabi biz işlemiyoruz her zamanki gibi, Zimbabwe’yi yeniden keşfetmenin alemi yok, yazmış adamlar.

Kullanacağımız kütüphane <getopt.h>. Adından da anlaşılacağı üzere, kullanıcı programı çağırırken hangi seçeneklerle çağırdıysa bunları bize sırasıyla veriyor.

Tabi konuyla ilgili bir takım teorik açıklamalarda da bulunmaktan yine kaçınmayacağım. Linuxta parametreler nasıl verilir?

Seçenekler uzunluklarına göre ikiye ayrılır. Evet doğru tahmin, uzun ve kısa olanlar olarak. Kısa seçenekler tek harftir. Uzun olanlar birden fazla harften oluşur. Genellikle uzun seçeneklerin aynı zamanda kısa halleri de mevcuttur. Örneğin gcc ye parametre veriyoruz, hus.c dosyasını, assembly haline (-c), gnu debuggerda debug edilebilecek şekilde (-gstabs), hus.o dosyasına yazılacak şekilde (-o hus.o) çalıştıralım.

gcc hus.o -o hus.o -c -gstabs

Tek karakterden oluşan ve parametre almayan seçenekler birlikte de yazılabilir. Örneğin ls yani list komutunda olduğu gibi

ls -lart

Evet bu şekilde konu hakkındaki bilgimizi tazeledikten sonra, programımıza geçebiliriz.

Öncelikle, konuyla ilgili struct’ımızı tanıyalım:

struct option {
const char * name;
int has_arg;
int * flag;
int val;
}

İlk değişken seçeneğe ait uzun isim, ikincisi argümana sahip olup olmadığı (0 yok, 1 var, 2 olabilir de olmayabilir de), dördüncüsü ise seçeneğin tek karakterlik hali. (üçüncü işimize yaramayacak)

Şimdi de kendimize yapacak bir iş bulalım. Programımız şu işi yapsın;

bilgisayar simdi gcc ile programimi derle(me)

cümlesinin, “bilgisayar” ve “programimi derle” dışındaki kısımlarını seçenek olarak alsın ve yazıp yazmayacağına öyle karar versin.

#include <stdio.h>
#include <getopt.h>
#include <string.h>
int main (int argc, char * argv[])
{
int sonraki;
// Cümlemizi bu dizide oluşturacağız
char yazi[100];
// Cümle olumsuz mu olumlu mu?
int olumsuz=0;
// Seçeneklerin kısa halleri. Argüman alan seçenekten sonra bir ":" koyuyoruz.
const char * kisa_s = "si:o";
// Seçeneklerin uzun halleri. Görüleceği gibi, ile seçeneği parametre aldığı için orada bir 1 var.
const struct option uzun_s[] = {
{"simdi", 0,NULL,'s'},
{"ile", 1,NULL,'i'},
{"olumsuz", 0,NULL,'o'},
{NULL,  0,NULL,0},
};
// Cümlemizin ilk kelimesi sabit, hemen yazıyoruz.
strcpy(yazi,"bilgisayar ");
do {
// getopt_long fonksiyonu her seferinde bize hangi seçenek varsa sırada, onun kısa halini verir. Eğer başka seçenek kalmadıysa -1, eğer hatalı giriş varsa '?' döndürür.
sonraki=getopt_long(argc,argv,kisa_s,uzun_s,NULL);
switch (sonraki)
{
// s seçeneği geldi
case 's':
strcat(yazi,"simdi ");
break;
// i seçeneği geldi

case 'i':
// eğer argümanı olan bir seçenek kullanıldıysa, getopt_long fonksiyonu bunu statik bir değişken olan optarg a yazar. Böylece argümanı oradan çekebiliriz
strcat(yazi,optarg);
strcat(yazi," ile ");
break;
case 'o':
olumsuz=1;
break;
case '?':
printf("Yanlis kullanim\n");
return 1;
break;
case -1:
break;

default:
// yağmur yağdı şimşek çaktı bir saçmalık oldu, switch deki caselerden hiç birine uymadı o zaman çıksın programdan, sigorta gözüyle bakabilirsiniz.
abort();
}
// başka argüman yok
}while(sonraki!=-1);

strcat(yazi,"programimi derle");
if (olumsuz)
{
strcat(yazi,"me");
}
strcat(yazi,".");
printf("%s\n",yazi);
return 0;
}

Bazı örnek çıktılar:

haytazade@gomputur getopt $ ./a.out -s -i gcc -o
bilgisayar simdi gcc ile programi derleme.
haytazade@gomputur getopt $ ./a.out -s -i gcc
bilgisayar simdi gcc ile programi derle.
haytazade@gomputur getopt $ ./a.out -i gcc
bilgisayar gcc ile programi derle.
haytazade@gomputur getopt $ ./a.out -i
./a.out: option requires an argument -- 'i'
Yanlis kullanim
haytazade@gomputur getopt $ ./a.out
bilgisayar programi derle.

Bu yazı toplamda 2328, bugün ise 0 kez görüntülenmiş

No Comments