PDA

Tam Sürümünü Görmek İçin : conio.h vs curses.h sorunsalı


ameximes
26/09/2005, 06:00
Merhabalar,
Bir GNU/Linux ve C çaylağı olarak elimden geldiğince lafı dolandırmadan sormaya çalışayım.
getch() ve clrsrc() fonksiyonları (ve elbette daha bir çok başka fonksiyonu da) barındıran başlık dosyası nedir? Elimdeki dökümanda örnek kod içerisinde conio.h dosyası kullanılmış, gcc "böyle bir dosya yok git burdan" dediğinde google'ı ve forumun aramalarını deşerek ulaşabildiğim sonuçlar, conio.h'daki kimi fonksiyonların curses.h'de tanımlı olduğundan söz ediliyordu ancak gcc curses.h'nin de sistemde olmadığını söylüyor. Search for Files v2.6 ile şöyle bir taradığımda "getch" ifadesi stdio.h'de görünüyor diyor ama o da yeterli gelmiyor. Dökümanda anlatılan her fonksiyon için "standarttır", "standart değil ama bir çok derleyicide var" gibi açıklamalar var ama getch için bir şey dememiş. Bu iki fonksiyon yapıları itibariyle muhakkak standarttır gibi geliyor bana ama bilemiyorum.

Şu kodda;
#include <stdio.h>
#include ŞÜPHELİ BAŞLIK
#include <string.h>

char *mystrstr(char *s1, char *s2);

int main()
{
char s1[100];
char s2[100];
char *ptr;

clrscr();
printf("aramanın yapılacağı yazıyı girin : ");
gets(s1);
printf("aranacak yazıyı girin :");
gets(s2);
ptr = mystrstr(s1, s2);
if (ptr)
puts(ptr);
else
puts("aradığınız yazı bulunamadı\n");
getch();
}


char *mystrstr(char *s1, char *s2)
{
int i, j;
int lens1, lens2;

lens1 = strlen(s1);
lens2 = strlen(s2);

for (i = 0; lens1 - i >= lens2; ++i, ++s1) {
for (j = 0; s1[j] == s2[j]; ++j)
if (s2[j + 1] == '\0')
return s1;
}
return NULL;
}


ŞÜPHELİ BAŞLIK yerine conio.h ya da curses.h denediğimde dosya bulunamadı; o satırı kaldırdığımda ise aşağıdaki hatayı alıyorum.

tga@ubuntu:~/c$ gcc mystr.c -o mystr
/tmp/ccCa9aQ0.o(.text+0x29): `main' İşlevinde:
: warning: the `gets' function is dangerous and should not be used.
/tmp/ccCa9aQ0.o(.text+0x11): `main' İşlevinde:
: undefined reference to `clrscr'
/tmp/ccCa9aQ0.o(.text+0x87): `main' İşlevinde:
: undefined reference to `getch'
collect2: ld çıkış durumu 1 ile döndü


Bu arada okunaiblirliği artsın diye c kodunu php diyerek renklendirerek eşşeklik etmedim umarım. Saat itibariyle de kafam durmuş gibi, eğer beceriksizce laflar ettiysem affola. Son olarak ne zaman "gets()" fonksiyonunu kullansam gcc korkuyor bundan, sebebini de sormak istedim. İlgi ve alakanız için çok teşekkür ederim.

Ek çıktılar:

tga@ubuntu:~/c$ gcc -v
Özellikler /usr/lib/gcc-lib/x86_64-linux/3.3.5/specs'den okunuyor
../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --enable-__cxa_atexit --enable-clocale=gnu --enable-debug --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc --disable-multilib x86_64-linux
seçenekleriyle yapılandırıldı.
Evre modeli: posix
gcc 3.3.5 (Debian 1:3.3.5-8ubuntu2) sürümü

AMD64 üzerinde Ubuntu AMD64 Hoary kullanıyorum.


mr1yh1
26/09/2005, 10:24
conio.h borland eklentisi, standard C de yok.
ama birileri gcc için de yazmış.
http://www14.brinkster.com/aditsu/console/
ben şu linki buldum, ama denemedim.

eğer elindeki dosyalar sağlamsa ( borlandınkiler değilse )
oradaki headers and libraries: yazan kısma bir bak.
-lconio ile ilgili kütüphaneyi bağlaman gerekiyormuş.

ameximes
26/09/2005, 13:46
Sevgili mr1yh1,
Vermiş olduğunuz bağdaki bilgilerde de olduğu gibi bu kütüphane dosyaları standart değiller. Yeni başlayan birisi olarak daha şimdiden standart dışı fonksiyonlar, kütüphaneler vs. ile çalışmamım pek doğru olmayacağını sanıyorum. Zira okuduğum kaynaklarda (belgeler.org) sürekli olarak bu konuda hassas olunması gerektiği işleniyordu. clrsrc() ve getch() gibi fonksiyonların standart dışı olması çok garip geldiğinden bunların zaten bir başlık dosyası içinde olacağını tahmin ediyordum. Eğer durum böyle değilse alternatiflerini bulmak için çabalamam daha doğru olacaktır sanırım ya da belki aynı işi görecek fonksiyonları kendim oluşturmaya çalışmalıyım, iyi pratik olur.

İlgi ve alakanız için sağolun.

ameximes
26/09/2005, 17:26
Tekrar merhaba,
The C library Reference Guide (http://www.acm.uiuc.edu/webmonkeys/book/c_guide/) bu kaynaktan edindiğim bilgi doğrultusunda, getch fonksiyonu yerine getchar() fonksiyonunu kullanarak kodu

root@ubuntu:/home/tga/c # gcc mystr.c -o mystr
/tmp/ccWGPdd4.o(.text+0x1f): `main' İşlevinde:
: warning: the `gets' function is dangerous and should not be used.


gibi bir çıktıyla da olsa derleyebildim. Şimdi bunun ne olduğunu anlamaya çalışacağım. Teşekkürler.

mr1yh1
26/09/2005, 17:40
int main()
{
char s1[100];
char s2[100];
char *ptr;

clrscr();
printf("aramanın yapılacağı yazıyı girin : ");
gets(s1);
printf("aranacak yazıyı girin :");
gets(s2);

}



uyarının nedeni buffer overflow u engellemek içinmiş.
yani gets ile aldığın veri s1ve s2 nin boyutunu aşarsa ne olacak ?
http://www.linuxjournal.com/node/6701/print

birileri bunu bilinçli olarak kullanıp ,
bufferın taşan kısmına makina dili kodu gönderiyor.
senin programının hakları ile gönderdiği kodu çalıştırabiliyor.

C++ tarzı IO kullandığım için , birşey öneremiyorum.

acehreli
26/09/2005, 21:09
ameximes, standart islevleri kullanma yonundeki kararin guzel; ama oyle bir karar verdigin zaman, klavye, ekran, yazici, vs. gibi C standardinin (ve C++) gozardi ettigi aygitlari kullanamayacaksin demektir.

Standartta ekran olmadigi icin, ekrani silmek icin clrscr; klavyeden beklemeden karakter okumak icin getch kullanamazsin. Standartta butun giris cikis akimlar (stdin, stdout, vs.) yoluyla yapilir; "ekranla" degil...

Eger program yalnizca ekrani olan ortamlarda calisacak uzere tasarlanmissa, ve o ortamlarin hepsinde <conio.h> varsa, hic olmazsa platformdan bagimsiz olma adina bence <conio.h> kullanilabilir.

gets konusu da mr1yh1'in dedigi gibi... Onu tamamen unutup yerine fgets islevini kullanmalisin. Sihirli sabitlerden kacinmak gerektigi icin, kod icindeki 100'ler yerine

#define DIZI_UZUNLUGU 100

seklinde bir makro tanimladiktan sonra,

gets(dizi);

yerine

fgets(dizi, DIZI_UZUNLUGU, stdin);

yazabilirsin. Gelen karakterlerin diziye sigmamis oldugu durumda ne yapacagin sana kalmis :)

Ali