2012-09-29 17 views
7

getchar()'u anlamakta zorlanıyorum. beklendiği gibi çalıştığını getchar aşağıdaki programda:scanf kullanırken hata durmuyor

#include <stdio.h> 


int main() 
{ 
    printf("Type Enter to continue..."); 
    getchar(); 
    return 0; 
} 

Ancak şu programda, getchar bir gecikme yaratmaz ve program sona erer:

#include <stdio.h> 

int main() 
{ 
    char command[100]; 
    scanf("%s", command); 
    printf("Type Enter to continue..."); 
    getchar(); 
    return 0; 
} 

aşağıdaki weired geçici çözümü işleri hangi Yani benim sorular burada

#include <stdio.h> 

int main() 
{ 
    char command[100]; 
    int i; 
    scanf("%s", command); 
    printf("Type Enter to continue..."); 
    while (getchar() != '\n') { 
     i=0; 
    } 
    getchar(); 
    return 0;  
} 

: ama nedenini anlamıyorum
nedir 1.yapıyor? Neden scanf bunu yapıyor?
2. Çalışmam neden işe yarıyor?

Eğer Yeni satır yazdığınız sonra giriş sadece programa gönderilir
raw_input("Type Enter to continue") 

cevap

9

ancak

scanf("%s", command); 

, newline bırakır: Aşağıdaki Python kodunu taklit için iyi bir yol nedir
3. Giriş arabelleği, (1) biçimindeki biçiminden sonra, boşluk olmayan bazı karakterlerden sonra ilk boşluk karakteriyle karşılaşıldığında, getchar() bu satırı hemen döndürür ve daha fazla giriş için beklemeye gerek yoktur.

Geçici çözümünüz, getchar() numaralı telefonu bir kez daha aramadan önce satır satırını giriş arabelleğinden temizlediğinden çalışır.

, scanf içinde %s çok güvensiz kullanarak o

scanf("%s", command); 
int c; 
do { 
    c = getchar(); 
}while(c != '\n' && c != EOF); 
if (c == EOF) { 
    // input stream ended, do something about it, exit perhaps 
} else { 
    printf("Type Enter to continue\n"); 
    getchar(); 
} 

(1) Not, davranışını taklit mesajı yazdırmadan önce giriş tamponu temizlemek için, ne tampon girdi kısıtlamalısınız can Bir alan genişliği ile tutun, scanf("%99s", command) en 99 (sizeof(command) - 1)) karakterleri 0-command, 0-terminatör için boşluk bırakarak okuyacaktır. Komut girişini aldıktan sonra, stdin'i yıkadıktan sonra

+0

+1 Stdin'in konsola bağlı kalması durumunda bir EOF'un benzer olup olmadığını merak ediyorum. Stdin’in bir dosyadan yönlendirilmesi, cevabımı daha az sağlam hale getirmesi şüpheli olabilir. – Clifford

+0

Muhtemelen değil, tabii ki akışı kapatmak için Ctrl-D (Ctr-Z Windows, iirc) yazabilirsiniz. Düzenleme için teşekkürler, btw. –

-2

.

fflush(stdin); 

ancak (Microsoft C kütüphanesi bir uzantısı olarak davranışını tanımlayan rağmen) tanımlanmamış bir davranış bir giriş akışı sonucu yıkama.

+2

fflush(), giriş akışları için tanımsızdır. – Clifford

+1

-1: fflush() işlevini bir giriş akışına (veya son işlemin girildiği bir girdi/çıktı akışına) uygulamak, [C Standard] tarafından belirtilen Tanımlanmamış Davranışın birkaç özel örneğidir (http://www.open-std.org/JTC1/sc22/wg14/www/docs/n1570.pdf). – pmg

+0

Bu, Microsoft'un C kütüphanesi ile çalışırken, kesinlikle GNU C kütüphanesinde bulunmadığını unutmayın. Önlemek. – Clifford

2

Beyaz boşluk, 5y3% s biçim belirtecinin sınırlayıcısıdır ve newline, boşluk olarak kabul edilir, bu nedenle arabelleğe alınmaya devam eder. Konsol girişi normalde hat yönelimli olduğundan, bir 'hat' tamponlu kaldığı için bir sonraki getchar() çağrısı hemen geri döner.böylece biraz daha farklı bir ihtiyaç Tek bir karakter almak için getchar() veya% c kullanırsanız

scanf("%s", command); 
while(getchar() != '\n'){ /* flush to end of input line */ } 

Eşit normalde hattını temizlemek gerekir, ancak bu durumda girilen karakter kendisi satır olabilir çözüm: getchar için benzer

scanf("%c", ch); 
while(ch != '\n' && getchar() != '\n'){ /* flush to end of input line */ } 

():

ch = getchar(); 
while(ch != '\n' && getchar() != '\n'){ /* flush to end of input line */ } 

elbette yapılacak mantıklı şey içine bu çözümleri sarılmasıdır Yeniden kullanabileceğiniz bağımsız giriş fonksiyonları ve ortak giriş doğrulama ve hata kontrol kodu koymak için bir yer olarak kullanabilirsiniz (Daniel Fischer'ın EOF için mantıklı bir şekilde kontrol ettiği gibi - normalde bu kontrolleri ve hataları kopyalamaktan kaçınmak istersiniz her yerde işleniyor).

2

İlk önce fgets kullanın ve girdiyi ayrıştırmak için sscanf kullanın. Uzun zamandır bu gibi şeyler yapıyorum ve davranış scanf düz kullanarak daha öngörülebilir olmuştur.

0

Eh, bir şey daha kolay: başka bir getchar() ekle ... sorun çözüldü!

+0

, sorunu çözmeyebilir, yine de tamponda birden fazla bayta sahip olabilirsiniz ve 'getchar()' sonra hemen geri dönecektir. – Pablo

İlgili konular