Próbuję napisać program w C ++, w którym przy wpisywaniu przez użytkownika dowolnego znaku z klawiatury powinien on przejść do następnej linii kodu.
Oto mój kod:
char c;
cin>>c;
cout<<"Something"<<endl;
ale to nie działa, ponieważ przechodzi do następnej linii tylko wtedy, gdy wprowadzam jakiś znak, a następnie wciskam ENTER.
LUB
Jeśli tego użyję
cin.get() or cin.get(c)
po naciśnięciu Enter przechodzi do następnego wiersza instrukcji.
Ale chciałem, żeby przesuwał się do następnej linii po naciśnięciu dowolnego klawisza na klawiaturze, jak to zrobić?
Odpowiedzi:
W systemie Windows:
system("pause");
oraz na Macu i Linuksie:
system("read");
wyświetli komunikat „Naciśnij dowolny klawisz, aby kontynuować ...” i oczywiście poczekaj na naciśnięcie dowolnego klawisza. Mam nadzieję, że to miałeś na myśli
źródło
system
wywołuje program zewnętrzny. Nie musisz dzwonić do zewnętrznego programu, aby czekać na jakikolwiek klucz! To tak, jak dzwonienie do innej osoby, aby włączyła komputer, gdy siedzisz przed nim - to powolne rozwiązanie.Jeśli korzystasz z systemu Windows, możesz użyć tego,
kbhit()
który jest częścią biblioteki wykonawczej firmy Microsoft. Jeśli używasz Linuksa, możesz zaimplementować wkbhit
ten sposób ( źródło ):#include <stdio.h> #include <termios.h> #include <unistd.h> #include <fcntl.h> int kbhit(void) { struct termios oldt, newt; int ch; int oldf; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); oldf = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); fcntl(STDIN_FILENO, F_SETFL, oldf); if(ch != EOF) { ungetc(ch, stdin); return 1; } return 0; }
Aktualizacja: Powyższa funkcja działa na OS X (przynajmniej na OS X 10.5.8 - Leopard, więc spodziewałbym się, że będzie działać na nowszych wersjach OS X). Tę treść można zapisać jako
kbhit.c
i skompilować zarówno w systemie Linux, jak i OS X zW biegu z
Monituje o naciśnięcie klawisza i kończy działanie po naciśnięciu klawisza (nie ogranicza się do klawiszy Enter lub drukowalnych).
@Johnsyweb - wyjaśnij, co masz na myśli przez „szczegółową odpowiedź kanoniczną” i „wszystkie wątpliwości”. Również ponownie „wieloplatformowy”: Dzięki tej implementacji
kbhit()
możesz mieć tę samą funkcjonalność w programie C ++ na Linux / Unix / OS X / Windows - o jakich innych platformach się odnosisz?Dalsza aktualizacja dla @Johnsyweb: aplikacje C ++ nie działają w hermetycznie zamkniętym środowisku C ++. Głównym powodem sukcesu C ++ jest interoperacyjność z C. Wszystkie główne platformy są zaimplementowane z interfejsami C (nawet jeśli wewnętrzna implementacja używa C ++), więc twoje określenie „starszego” wydaje się nie na miejscu. Dodatkowo, skoro mówimy o pojedynczej funkcji, dlaczego potrzebujesz do tego C ++ („C z klasami”)? Jak już wspomniałem, możesz pisać w C ++ i mieć łatwy dostęp do tej funkcjonalności, a użytkownicy Twojej aplikacji raczej nie będą przejmować się tym , jak ją zaimplementowałeś.
źródło
kbhit()
funkcja deklarujeterminal_settings
zmienną w linii, która wydaje się nic nie robić, a jednak robi wszystko. Niektórzy mogą pomyśleć, że to fajne, ale uważam, że jest to niejasne do tego stopnia, że jest nieczytelne.Nie ma całkowicie przenośnego rozwiązania.
Pytanie 19.1 z często zadawanych pytań dotyczących comp.lang.c zawiera szczegółowe omówienie rozwiązań dla systemu Windows, systemów uniksopodobnych, a nawet MS-DOS i VMS.
Szybkie i niepełne podsumowanie:
curses
biblioteki; wywołanie,cbreak()
po którym następujegetch()
(nie mylić zgetch()
funkcją specyficzną dla systemu Windows ). Zauważ, żecurses
generalnie przejmuje kontrolę nad terminalem, więc prawdopodobnie będzie to przesada.ioctl()
do manipulowania ustawieniami terminala.tcgetattr()
itcsetattr()
może być lepszym rozwiązaniem.system()
systemie Unix można użyć do wywołaniastty
polecenia.getch()
lubgetche()
.SMG$
) procedury zarządzania ekranem ( ) mogą załatwić sprawę.Wszystkie te rozwiązania C powinny działać równie dobrze w C ++; Nie znam żadnego rozwiązania specyficznego dla C ++.
źródło
Aby osiągnąć tę funkcjonalność, możesz skorzystać z biblioteki ncurses, która została zaimplementowana zarówno na Windowsie, jak i na Linuksie (i MacOS o ile wiem).
źródło
W systemie Windows ten krótki program osiąga cel:
getch
wstrzymuje konsolę do momentu naciśnięcia klawisza ( https://www.geeksforgeeks.org/difference-getchar-getch-getc-getche/ )#include<iostream.h> #include<conio.h> using namespace std; void check() { char chk; int j; cout<<"\n\nPress any key to continue..."; chk=getch(); j=chk; for(int i=1;i<=256;i++) if(i==j) break; clrscr(); } void main() { clrscr(); check(); cout<<"\n\nIt works!"; getch(); }
Należy zauważyć, że getch nie jest częścią biblioteki standardowej.
źródło
getch()
różni się odcin.get
lubcin>>
, być może niektóre łącza do dokumentacjiPrzyjrzałem się temu, co próbujesz osiągnąć, ponieważ pamiętam, że chciałem zrobić to samo. Zainspirowany Vinayem napisałem coś, co działa dla mnie i trochę to rozumiem. Ale nie jestem ekspertem, więc proszę, bądź ostrożny.
Nie wiem, skąd Vinay wie, że używasz Mac OS X. Ale powinno to działać mniej więcej tak z większością systemów unixopodobnych. Naprawdę pomocne, ponieważ zasób jest opengroup.org
Pamiętaj, aby opróżnić bufor przed użyciem funkcji.
#include <stdio.h> #include <termios.h> //termios, TCSANOW, ECHO, ICANON #include <unistd.h> //STDIN_FILENO void pressKey() { //the struct termios stores all kinds of flags which can manipulate the I/O Interface //I have an old one to save the old settings and a new static struct termios oldt, newt; printf("Press key to continue....\n"); //tcgetattr gets the parameters of the current terminal //STDIN_FILENO will tell tcgetattr that it should write the settings // of stdin to oldt tcgetattr( STDIN_FILENO, &oldt); //now the settings will be copied newt = oldt; //two of the c_lflag will be turned off //ECHO which is responsible for displaying the input of the user in the terminal //ICANON is the essential one! Normally this takes care that one line at a time will be processed //that means it will return if it sees a "\n" or an EOF or an EOL newt.c_lflag &= ~(ICANON | ECHO ); //Those new settings will be set to STDIN //TCSANOW tells tcsetattr to change attributes immediately. tcsetattr( STDIN_FILENO, TCSANOW, &newt); //now the char wil be requested getchar(); //the old settings will be written back to STDIN tcsetattr( STDIN_FILENO, TCSANOW, &oldt); } int main(void) { pressKey(); printf("END\n"); return 0; }
O_NONBLOCK też wydaje się być ważną flagą, ale nic mnie to nie zmieniło.
Doceniam, jeśli osoby z głębszą wiedzą skomentują to i udzielą porady.
źródło
Możesz użyć specyficznej dla Microsoft funkcji _getch :
#include <iostream> #include <conio.h> // ... // ... // ... cout << "Press any key to continue..." << endl; _getch(); cout << "Something" << endl;
źródło
Działa to na platformie Windows: wykorzystuje bezpośrednio rejestry mikroprocesora i może być używane do sprawdzania naciśnięcia klawisza lub przycisku myszy
#include<stdio.h> #include<conio.h> #include<dos.h> void main() { clrscr(); union REGS in,out; in.h.ah=0x00; printf("Press any key : "); int86(0x16,&in,&out); printf("Ascii : %d\n",out.h.al); char ch = out.h.al; printf("Charcter Pressed : %c",&ch); printf("Scan code : %d",out.h.ah); getch(); }
źródło
Jeśli używasz programu Visual Studio 2012 lub starszego, użyj
getch()
funkcji, jeśli używasz programu Visual Studio 2013 lub nowszego, użyj_getch()
. Będziesz musiał użyć#include <conio.h>
. Przykład:#include <iostream> #include <conio.h> int main() { std::cout << "Press any key to continue. . .\n"; _getch(); //Or getch() }
źródło
Możesz użyć procedury getchar .
Z powyższego linku:
/* getchar example : typewriter */ #include <stdio.h> int main () { char c; puts ("Enter text. Include a dot ('.') in a sentence to exit:"); do { c=getchar(); putchar (c); } while (c != '.'); return 0; }
źródło
Możesz także użyć getch () z conio.h. Takie jak to:
...includes, defines etc void main() { //operator getch(); //now this function is waiting for any key press. When you have pressed its just //finish and next line of code will be called }
Tak więc, ponieważ UNIX nie ma conio.h, możemy symulować getch () za pomocą tego kodu (ale ten kod został już napisany przez Vinary, moja porażka):
#include <stdio.h> #include <termios.h> #include <unistd.h> int mygetch( ) { struct termios oldt, newt; int ch; tcgetattr( STDIN_FILENO, &oldt ); newt = oldt; newt.c_lflag &= ~( ICANON | ECHO ); tcsetattr( STDIN_FILENO, TCSANOW, &newt ); ch = getchar(); tcsetattr( STDIN_FILENO, TCSANOW, &oldt ); return ch; }
źródło
Jeśli teraz wyszukasz funkcję kbhit () w witrynie MSDN, zobaczysz, że jest ona przestarzała. Zamiast tego użyj _kbhit ().
#include <conio.h> int main() { _kbhit(); return 0; }
źródło
#include <iostream> using namespace std; int main () { bool boolean; boolean = true; if (boolean == true) { cout << "press any key to continue"; cin >> boolean; } return 0; }
źródło
Po prostu użyj
system("pause");
polecenia.Wszystkie inne odpowiedzi komplikują sprawę.
źródło