2016-04-12 36 views
5

Standart bir C işlevi olarak dahil edilmek üzere, getch'in doğal olarak ulaşılmaz kılan nedir?Neden getch taşınabilir değil?

Konsol arabirimleri için çok sezgisel ve zarif. Bu olmadan, tek bir karakter istemek her zaman yanıltıcıdır çünkü kullanıcılar birden fazla tuşa girebilir.

Daha da kötüsü, genellikle standart bir özellik olarak sağlanmayan, konsol girişini okuduktan sonra standart girişi temizlediğinizden emin olmanız gerekir! Kendi başımı kullanmalıyım!

Basit bir program olabilir ki:

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <conio.h> 

int main(int argc, char **argv) 
{ 
    while (1) { 
     char yes_or_no;   

     printf("is this statement correct? 1 + 1 = 2(Y/N) $ "); 
     yes_or_no = tolower(getch()); 

     switch (yes_or_no) { 
      case 'y': 
       puts("Right!");  
       goto done; 

      case 'n': 
       puts("\nhint> Please just say yes for the sake of this demo..."); 
       break; 

      case 'q': 
       puts("\nExitting."); 
       goto done; 

      case EOF: 
       puts("\nEOF."); 
       goto done; 

      default: 
       printf("\nunknown response '%c'.\n", yes_or_no); 
       break; 
     } 
    } 


done: 
    return 0; 
} 

olur:

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 

static inline void flush_stdin() 
{ 
    char ch; 

    do { 
     ch = getchar(); 
    } while ((ch != '\n') && (ch != EOF)); 
} 

int main(int argc, char **argv) 
{ 
    while (1) { 
     char yes_or_no;   

     printf("is this statement correct? 1 + 1 = 2(Y/N) $ "); 
     yes_or_no = tolower(getchar()); 


     switch (yes_or_no) { 
      case 'y': 
       puts("Right!");  
       goto done; 

      case 'n': 
       puts("hint> Please just say yes for the sake of this demo..."); 
       break; 

      case EOF: 
       puts("EOF."); 
       goto done; 

      default: 
       printf("unknown response '%c'.\n", yes_or_no); 
       break; 
     } 
     flush_stdin(); /* remove this to see the difference */   
    } 


done: 
    return 0; 
} 

ben basit portatif konsol programı yapmak istiyorum her zaman, böyle fonksiyonların bir demet yapma zorla hissediyorum ve hala getch gibi istediğim her şeye sahip olmayacağım.

Elbette küfürleri kullanabilirsiniz, ancak küfürler tüm konsolunuzu ele geçirir ve programınızın normal bir kullanıcının beklediğinden farklı bir şekilde davranmasını sağlar (programın yalnızca kaydırılması ve programın çalıştırıldığı komutu göstermesi için konsol tamponu).

"Neden" in kötü bir soru olduğunu (her zaman neyin tercih edilmesi gerektiğini) biliyorum, ama sorulmalı. Bir masaüstü sisteminin destekleyemediği bir getch içinde doğal olarak ulaşılmaz bir şey var mı? Eğer yoksa, kendim yazabilirim ve desteklemek istediğim tüm platformlara taşıyabilirim ve iyiyim.

Eğer getch bir şey varsa, bu bir masaüstü sistem tarafından desteklenemez mi, ne var? Bu yüzden, conio'nun niçin kullanıldığını anlamak için daha iyi bir nedenim var: "sadece ncurses/conio standart değil".

+1

Btw, '' '' int' türünde olmalıdır. – pzaenger

+0

Biçimlendirilmiş I/O ('scanf' /' printf') ve biçimlendirilmemiş I/O ('getchar' /' putchar') karışımından kaçınmaya çalışırsanız, buna bile gerek yoktur. – edmz

+0

@pzaenger Biliyorum, ama bunu EOF ile karşılaştırmayı geçersiz kıldım çünkü bunu sadece 1 bayt yerine 4 bayt ile karşılaştırıp ek bir cast ekleyeceğim. Bu yaygın bir hatadır. -black: ve bu detay açık değildir ve daha kullanıcı dostu kütüphane tasarımı ile önlenebilecek ince hatalara neden olur. – Dmitry

cevap

5

C standardında, terminal veya Windows kavramı yoktur. Bu şeylerle ilgili her şey uygulamaya özgüdür ve C programlama dilinin bir parçası olamaz. Bununla birlikte, terminal programlama için endüstri standartları bulunmaktadır. Biri, POSIX'in (IEEE 1003.1) termi- nimleri terminal sürücüsü arabiriminin bir parçası olup, biri terminali daha yüksek düzeyde işlemek için C işlevlerinin bir kütüphanesini belirten X/Açık küfürler ve üçüncü ise ISO 6429, ANSI kümesidir terminal kaçış dizileri.

Tesadüfen, X/Açık küfürler bir getch() işlevi sağlar. Microsoft Windows ayrıca bu standartları desteklemektedir, ancak yararlı bir şekilde değil. conio.h kolayca dolayı konsol DOS vs. nasıl çalıştığını farklı modele diğer platformlarda hayata olamaz bir DOS özgü başlık olarak

sen (yani conio.h aracılığıyla) Windows üzerinde getch() kullanacağı yolu olsa taşınabilir değildir diğer platformlardaki terminaller.

+0

Terminios'u tamamen unutmuşum, kontrol etmeliyim. Bana hatırlattığın için teşekkürler. – Dmitry

+0

ama bir karakter için eaco'yu kapatmak, bir karakteri okumak ve döndürmek için gerçekten bir terminal/pencere nosyonuna ihtiyacınız var mı? Standart keyO yüksek seviyeli olmak zorundaysa, tuşa basmanın hiçbir yolu yoktur ve sadece tam dizge girişlerinde çalışmalı mıdır? Bu şeyleri taşınabilir hale getirmenin tek yolu mu? – Dmitry

+0

@Dmitry Bu konuda yeni bir soru açabilirsin (biraz söylemek gerekirse). Ama kısaca, cevap evet, standart bunu umursamıyor; §1.2 N1570 _ "Bu Uluslararası Standart şunları belirtmez: [...] bir C programı tarafından kullanılmak üzere giriş verilerinin dönüştürüldüğü mekanizmadır." _ – edmz