2008-11-06 16 views
10

Używam getch() i moja aplikacja ulega natychmiastowej awarii. W tym przypadku robi:Odpowiednik getch Windows() na awarie Mac/Linux

int main() 
{ 
    getch(); 
} 

nie mogę znaleźć linku, ale podobno problem jest to, że musi wyłączyć buforowanie lub coś dziwnego w tym kierunku, a ja nadal chce cout do pracy wraz z krzyżem kodu platformy.

Powiedziano mi, że należy używać std::cin.get(), ale chciałbym, aby aplikacja została zamknięta po naciśnięciu klawisza, a nie wtedy, gdy użytkownik wpisał literę lub cyfrę, a następnie naciśnij klawisz Enter, aby zakończyć.

Czy jest w tym funkcja? Kod musi działać pod Mac (mój system operacyjny) i Windows.


Łączenie/kompilacja nie jest issue; Dołączam <curses.h> i łączę z -lcurses w XCode, podczas gdy Windows używa <conio.h>.

+0

Należy zauważyć, że "cout" jest konstrukcją C++. Chociaż dotychczasowe odpowiedzi dotyczą głównie języka C, będą również miały zastosowanie w C++. I std :: cin.get() utknąłby w oczekiwaniu na linię wejścia terminala - syndrom "Hit Enter" - tak samo jak getchar() lub jakakolwiek inna standardowa funkcja I/O. –

Odpowiedz

11

Czy przejrzałeś w <curses.h>, aby sprawdzić, co robi funkcja getch()?

Podpowiedź: OSX i Linux nie są takie same jak Windows.

Konkretnie, jako makro w <curses.h>, znajdziemy:

#define getch() wgetch(stdscr) 

Teraz pojawia się na systemie, aby być rzeczywista funkcja getch() w bibliotece curses, ale oczekuje stdscr należy skonfigurować i odbywa się to za pomocą funkcji inicjalizacji curses (initscr() i krewnych), a to nie jest wykonywane przez Twój kod. Tak więc twój kod wywołuje niezdefiniowane zachowanie przez wywołanie procedur curses przed wykonaniem prawidłowej inicjalizacji, co prowadzi do awarii.

(Dobra wskazówka od dmckee - to pomogło uzyskać linię łącza z acidzombie24, co było ważne.)

Aby dostać się do punktu, w którym pojedynczy klawisz skoku mogą być odczytywane i program zakończony czysto, ty dużo pracy nad Uniksem (OSX, Linux). Będziesz musiał przechwycić stan początkowy terminala, ustawić funkcję atexit() - lub jakiś podobny mechanizm - aby przywrócić stan terminala, zmienić terminal z gotowanego na surowy, a następnie wywołać funkcję odczytu znaku (prawdopodobnie tylko read(0, &c, 1)) i do wyjścia. Mogą być na to inne sposoby - ale na pewno będzie to wymagało pewnych operacji konfiguracji i wyładowania.

Jedna książka, która może pomóc Advanced Unix Programming, 2nd Edn autorstwa Marka Rochkinda; obejmuje obsługę terminalu na wymaganym poziomie. Alternatywnie możesz użyć odpowiednio: <curses.h> - będzie to prostsze niż rozwiązanie typu "roll-your-own" i prawdopodobnie bardziej niezawodne.

2

Nie wykazywał

#include <stdio.h> 

lub

#include <curses.h> 

lub podobną linię. Czy na pewno łączysz się z biblioteką zawierającą zawierającągetch()?

+0

Łączenie/kompilowanie nie jest problemem, ja dołączam curses i do -lcurses w xcode. window używa conio.h –

-1

Funkcja getch nie jest dostępna w systemach uniksowych, ale można ją zastąpić poleceniami konsoli za pomocą kompilatora za pomocą funkcji system.

Zastosowanie:

W systemie Windows można użyć system("pause");

w systemach Unix-like (takich jak OSX) można użyć system("read -n1 -p ' ' key");

Uwaga: system jest zadeklarowana w <stdlib.h>.

+0

to wstrzyma twój program, dopóki użytkownik nie kliknie klucza -nego klawisza - tak jak w 'getch();' – David

+3

Proszę powstrzymać się od sugerowania wywołań 'system()'. Jest to zła praktyka programowania i ma złe efekty uboczne. – user2064000

0

Użyj funkcji cin.get() na przykład:

#include <iostream> 

using namespace std; 

int main() 
{ 
    char input = cin.get(); 

    cout << "You Pressed: " << input; 
} 

Program będzie następnie czekać na wciśnięcie klawisza.

Po naciśnięciu klawisza zostanie wydrukowany na ekranie.

+0

Lub po prostu użyj funkcji getchar() – Benjamin