Gönderen Konu: C hakkında bir soru  (Okunma sayısı 4431 defa)

Çevrimdışı Fatih Beştaş

  • OTOKON Üyesi
  • *
  • İleti: 316
C hakkında bir soru
« : Mart 06, 2017, 06:38:16 ÖS »
#include<stdio.h>
int main()
{

int sayi;
a : printf("1 ile 5 arasinda bir sayi giriniz: ");
scanf("%d",&sayi);
switch(sayi)
{
case 1: printf("1'e bastiniz.\n"); break;
case 2: printf("2'ye bastiniz.\n"); break;
case 3: printf("3'e bastiniz.\n"); break;
case 4: printf("4'e bastiniz.\n"); break;
case 5: printf("5'e bastiniz.\n"); break;
default : printf("Gecersiz bir deger girdiniz.\n\n"); goto a;

}



}

Bu programı çalıştırdığımda herhangi bir sayı girdiğim zaman düzgün çalışıyor ama sayı dışında bir karakter mesela harf veya noktalama işareti girince program kendini hiç durmadan tekrarlamaya başlıyor ve ekranı kapatana kadar durmuyor. Bunun nedenini açıklayabilecek var mı acaba?
int yerine char ile denedim o zamanda farklı bir durumla karşılaştım sanırım char ın kullanımını düzgün yapamadım.

bilbeyt

  • Ziyaretçi
Ynt: C hakkında bir soru
« Yanıtla #1 : Mart 06, 2017, 06:54:04 ÖS »
5'e kadar olan sayılar için case tanımlamasını yapmışsınız. Bunun dışındaki her şey için program default case'i kullanır ki o da go to a; içeriyor. Bu yüzden program kendini tekrarlar. a pozisyonu sizin sayı istediğiniz yer.

Çevrimdışı İlker Kesen

  • Mezun olmuş OTOKON'cu
  • *
  • İleti: 1246
  • Boğduruyorum.
Ynt: C hakkında bir soru
« Yanıtla #2 : Mart 06, 2017, 07:34:02 ÖS »
Karakterler sayi olarak nasil represente ediliyor tam olarak bilmiyorum. Ama sonsuza kadar accumulate olan bir karakter var, yani sen scanf'te sayi girilmesi gereken yere sayi yerine char girdigin zaman, girdi-cikti stream'ine birden fazla sayi gondermis gibi oluyorsun, onlar da accumulate olup sonsuz donguye sebep oluyor. scanf'ten sonra getchar fonksiyonunu kullanarak bahsettigin problemi cozebilirsin. Hatta getchar kullanmak genelde cok daha guvenli. Sen klavyede enter'a bastigin zaman newline karakteri ('\n' karakteri) de girdi/cikti akisina giriyor. Onu handle etmek icin cogu zaman getchar kullanmak lazim (scanf'ten sonra).

Bir de geriye dogru goto kullanmasan, fazla alismadan kullanmayi biraksan senin icin cok daha guzel olur.

Çevrimdışı Fatih Beştaş

  • OTOKON Üyesi
  • *
  • İleti: 316
Ynt: C hakkında bir soru
« Yanıtla #3 : Mart 06, 2017, 09:49:25 ÖS »
scanf'ten sonra getchar girince sorun düzeldi teşekkürler. Ama aklıma takılan bir şey var getchar(); ın orada tam olarak nasıl bi görevi var biraz açıklayabilir misin?

Çevrimdışı İlker Kesen

  • Mezun olmuş OTOKON'cu
  • *
  • İleti: 1246
  • Boğduruyorum.
Ynt: C hakkında bir soru
« Yanıtla #4 : Mart 06, 2017, 10:01:35 ÖS »
Integer degisken icin char girince tam olarak ne oluyor ben de bilmiyorum. Ama soyle varsayalim. Mesela pes pese iki tane char degiskenini almaya calis scanf ile. Atiyorum a karakteri girip enter'a basiyorsun. Sen enter'a bastigin anda girdi akisina (STDIN oluyor bu durumda) a karakteri disinda \n karakterini de sokmus oluyorsun. Yani input olarak a\n gondermis oluyorsun. Boyle oldugu icin de ikinci scanf'in \n karakterini yakaliyor girdi akisindan ve ikinci defa input alamiyorsun kullanicidan. O vakada getchar ile o newline karakterini yakalamis oluyorsun girdi akisindan. Senin uygulaman integer beklerken karakter girilince de benzer bir durum ile karsilasiyor olsan gerek (tam bilmiyorum).

Çevrimdışı Ufuk Sevim

  • Mezun olmuş OTOKON'cu
  • *
  • İleti: 451
Ynt: C hakkında bir soru
« Yanıtla #5 : Mart 07, 2017, 05:51:04 ÖS »
Olayın '\n' karakteriyle alakası yok. Olay şu: fonksiyon beklediği bir değer göremeyince STDIN'i boşaltmıyor ve (bu durumda) 0 değerini dönüyor.

Alıntı
On success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.

Yani fonksiyonun dönüş değerinin 0'dan büyük olduğunu kontrol etmelisin devam etmeden önce. Yoksa STDIN boşalmadığı için hep aynı karakteri okumaya çalışırsın.
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

Çevrimdışı Fatih Beştaş

  • OTOKON Üyesi
  • *
  • İleti: 316
Ynt: C hakkında bir soru
« Yanıtla #6 : Mart 08, 2017, 04:00:29 ÖS »
Biraz araştırma yaptım ve şu fonksiyonu öğrendim fflush. Bu fonksiyonu programa scanf'ten sonra fflush(stdin); şeklinde eklediğimizde yanlış değer girilmesinden kaynaklı olan bu sorunu çözüyor. Anladığım kadarıyla bir nevi STDİN'i boşaltmaya yarayan bir fonksiyon.

Çevrimdışı Ufuk Sevim

  • Mezun olmuş OTOKON'cu
  • *
  • İleti: 451
Ynt: C hakkında bir soru
« Yanıtla #7 : Mart 08, 2017, 10:32:31 ÖS »
Biraz araştırma yaptım ve şu fonksiyonu öğrendim fflush. Bu fonksiyonu programa scanf'ten sonra fflush(stdin); şeklinde eklediğimizde yanlış değer girilmesinden kaynaklı olan bu sorunu çözüyor. Anladığım kadarıyla bir nevi STDİN'i boşaltmaya yarayan bir fonksiyon.

Bu fonksiyonu özellikle yazmadım sen araştırıp bulasın diye :) fflush (ve diğer fxxxx fonksiyonları) sadece STDIN için değil tüm stream'lerde kullanılabilir. Dosyalar, haberleşme aygıtları, vs. streamlere örnek olarak verilebilir.
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.