2009-09-16 8 views
6

왜 내 교수는 두 개의 getchar(); 우리 C 프로그램 튜토리얼의 끝에서?왜 내 교수는 두 개의 getchar();

그리고이 "더 좋은 방법"은 무엇입니까?

+63

수업 시작/끝내기를 요청 했습니까? – crashmstr

+6

가서 물어보십시오. 어쩌면 그는 영리 해 지려고 노력 중입니다. –

+4

더 좋은 방법은 입력 버퍼에 읽지 않은 문자가 있기 때문에 프로그램 끝에서 getchar을 여러 번 호출하는 자체 수정 프로그램이라고 생각합니다. 아시다시피, 때로는 두 가지로도 충분하지 않습니다. ;) – UncleBens

답변

15

가장 좋은 방법은 시도하고 콘솔 창을 계속 열어 두려면 코드를 추가 할 수 없습니다.

당신이 IDE에서 프로그램을 시작하고 사용자가 Enter 키를 누를 전에 프로그램이 종료되지하려는해야하는 경우, 하나의 getchar()가 수행해야합니다.

사용자가 키를 누른 후에 프로그램을 종료하는 두 번째 가장 좋은 방법은 보류중인 입력이 없는지 항상 확인하고 하나의 getchar()을 사용하는 것입니다.

선생님이 2 getchar() 사용하는 이유는, 내 생각, 이미 이전의 입력에서 입력 버퍼의 문자가 있다는 것입니다. 하고 Enter를 포함하여 최대 입력에서 모든 문자를 소비하려면이 보통이다 :

int ch; 
/* ... */ 
printf("Press Enter"); fflush(stdout); 
while ((ch = getchar()) != '\n' && ch != EOF) /* void */; 
+0

은 C 또는 C++의이 구문입니까? – HollerTrain

+5

이것은 표준 C 관용구입니다. 나는 C++에서도 작동한다고 믿지만 그 언어에서는 관용적이지 않을 수도있다. – pmg

+0

[Veganaize] (https://stackoverflow.com/users/5039027/veganaize)는'printf(); 대신'puts()'를 제안했다. fflush (stdout);'.저의 선택 이유는 깜박이는 커서를 "Press Enter"텍스트와 같은 줄에 두는 것입니다. 'puts()'는'fflush()'호출을 중복되게하는 개행을 자동으로 추가합니다. – pmg

23

사용자 입력을 기다리고있어 프로그램 출력을 볼 수 있습니다. 그렇지 않으면 프로그램이 완료되고 출력이 보이지 않습니다 (OS에 따라 다름). 그것을 가지고 그것을 시도하십시오.

+26

당신이 공부를 계속할 때이 답을 기억하십시오 - "시험을 치고 시도하십시오"는 우리가하는 일에서 매우 유용한 도구입니다. 때로는 팅커를 두려워하지 마십시오. – Steven

0

getchar(); 프로그램의 마지막에 "계속하려면 아무 키나 누르십시오"라는 상황이 만들어집니다. 나는 그가 어떤 키를 두 번 치는 것을 좋아한다는 것을 짐작하고있다.

+0

키를 두 번 누르는 것이 좋다고 생각하지 않습니다. 나는 getchar()를 하나만 넣으면 작동하지 않는다는 것을 깨달았습니다. 내 예를 보아라. – Lucas

1

아마 IDE에서 프로그램을 실행할 때 출력 창을 열어 두는 것이 좋습니다.

... 왜 저기에 두 개가 있습니다.

3

(아마도) 명령 행 프로그램을 일시 중지하십시오. 그는 하나만 사용하면 효과가 없으므로 이유가 무엇인지 알 수 없으므로 2 개를 사용하고 있습니다.

더 나은 해결책을 찾으면 (그리고 std :: cin이 아니라면) 영웅이 될 것입니다. 오늘의.

+0

예 나는이 해결책을 찾으려고 노력하고있다 :) 그는 학기의 후반부에 그것을 커버 할 것이지만 나는 지금 알아 내고 싶다고 말했다. – HollerTrain

+0

글쎄, 우선 getchar()가 사용하는 버퍼가 이미 첫 번째 getchar()을 건너 뛰거나 적어도 멈추지 않는 char을 포함하기 때문에 그는 '속임수'를 수행하고 있습니다. 버퍼를 먼저 비울 수 있습니까? (System ("sleep")이 아닌) 일시 중지를위한 다른 방법을 사용하십시오! – Jake

0

버퍼에서 나머지 "\ n"을 가져 와서 응용 프로그램을 닫습니다.

+0

버퍼에 여전히 무언가가 있다면 앱도 닫지 않습니까? – Lucas

+0

그가 왜 두 번이나 그런 이유가 아닌가? – Jake

16

그는 콘솔을 열어두고 사용자가 키를 누를 때까지 기다립니다. 나는 "getchar()"위의 교수 프로그램에서 무슨 일이 일어나는지에 따라 기억하고 있다고 생각합니다. 버퍼에 여전히 무언가가있을 수 있으므로 두 번째 "getchar()"을 추가했습니다. 정확하게 문제를 해결하는 가장 우아한 방법은 아닙니다.

편집 : 다음은 약간의 예입니다. "scanf()"에서 여전히 버퍼에 나머지 "\ n"이 있습니다. 두 번째 "getchar()"을 추가하면 예상 결과가 나타납니다. "getchar()"전에 버퍼를 플러시해야합니다.

#include <stdio.h> 

main() 
{ 
int input; 
scanf("%d", &input); 
printf("The input is %d\n", input); 
getchar(); 
return 0; 
} 

편집 2 : 여기 here에서 찍은 솔루션입니다. "엔터"버튼을 한 번 히트 Windows에서 문자를 생성

int c; 
printf("Press ENTER to continue... "); 
fflush(stdout); 
do c = getchar(); while ((c != '\n') && (c != EOF)); 
+0

그리고 다른 모든 사람들이 이미 이것을 알고 있다고 생각합니다. 버퍼 문제를 이해하는 유일한 사람으로 보입니다. – abyx

+0

@byx 버퍼 문제는 꽤 알려져 있지만 버퍼를 플러시하지 않아야합니다. 아니면 심지어 시스템 ("PAUSE"); – Agos

+3

시스템 ("PAUSE")은 플랫폼에 따라 다르며 Windows에서만 작동합니다. – Lucas

-3

때문에, wikipedia를 참조하십시오. 적어도 그것은 초보자의 많은 것이 필요 자신의 코드에 getch 전화를 넣어 기분이 ... 멀리 멀리 은하에서 너무 오래 전

+1

아니, 그건 그걸로 할 수 없어요. –

+0

stdin은 "텍스트"(바이너리와 반대) 스트림으로 열립니다. 이는 입력 키가 눌려지면 '\ n'만 읽는 것을 의미합니다. – Artelius

+0

- 그리고 Enter 키를 눌러 두 문자가 생성 되더라도 프로그램을 종료하기 전에 첫 번째 문자 만 기다려야합니다. – Artelius

5

이유를 하나의 호출이 자주하지 않는다는 것입니다 사용 작업.

그 이유는 getch이 입력 대기열에서 다음 키보드 입력을 가져 오기 때문입니다. 불행히도,이 큐는 사용자가 키보드의 키를 누를 때마다 채워지는데, 애플리케이션이 그 순간에 입력을 기다리지 않더라도 (전체 입력을 읽지 않는 경우 라하더라도 - 예를 들어 Lulu의 답변 참조). 결과적으로 getch은 입력 대기열 에서 을 기다리지 않고 문자를 가져옵니다. 다음은 키 누름입니다. 이는 프로그래머가 원하는 것입니다.

물론이 "솔루션"은 키보드 대기열에 문자가 하나 이상인 경우에도 많은 경우 실패합니다. 더 나은 해결책은 플러시 큐에 있고 다음에 다음 문자를 요청하는 것입니다.불행히도 C/C++에서이 작업을 수행 할 수있는 플랫폼 독립적 인 방법은 없습니다. C에서이 작업을 수행하는 기존의 방법은 ++ (죄송합니다, 내 C가 제한됩니다) 다음과 같습니다

std::cin.ignore(std::cin.rdbuf()->in_avail()); 

이 단순히 효과적으로 입력 큐를 삭제 가능한 모든 입력을 무시합니다. 불행히도,이 코드는 항상 (아주 비밀스러운 이유로) 작동하지 않습니다. 오른쪽 콘솔 창에서 프로그램을 시작

+0

홍조에 대해서는 어떻게 된거 야? void clearStdin() { int c; while ((c = getchar())! = EOF && c! = '\ n'); }; – Christian

+0

@Christian 전적으로이 방법이 가능하지만 위의 C++ 코드가 때때로 실패하는 것과 같은 이유로 실패 할 수 있습니다. –

+0

질문은'getch'가 아니라'getch'에 관한 것입니다. –

5

왜이 getchar가를 사용하여 내 교수()이다; 우리 C 프로그램 튜토리얼의 끝에서?

당신 누르면되는 입력 한 후 때까지 반환하지 않습니다

int main (void) 
{ 
    int  input; 

    scanf ("%d", &input); 

    printf ("The input is %d.\n", input); 

    getchar(); 
    getchar(); 

    return 0; 
} 

scanf 때문에 같은 뭔가를 가정하지만,에서 '\ n을'이 될 것입니다 당신이 다른 문자 입력 입력 버퍼에 입력됩니다.

그래서 위 및 1234 입력 입력을 실행하는 경우, 프로그램은 다음 다시를 입력 누를 때까지 The input is 1234.를 인쇄 한 후 일시 중지됩니다. 첫 번째 getchar은 첫 번째 과 연결된 '\n'을 읽습니다.을 입력합니다. 1234Space을 입력하면 프로그램이 일시 중지되지 않습니다. 먼저 getchar이 공백을 읽습니다. 두 개의 문자가 충분하지 않을 수 있으며 입력을 처리하기위한 코드에 응답을 인쇄하기위한 코드가 산재 해 있습니다.

그리고이에 대해 "더 나은 방법"은 무엇인가?

이 플랫폼을 입력 버퍼에 텍스트를 무시하는 구체적인 방법도 있습니다 C.에서 입력을 읽는 다양한 표준 방법이 있지만, 당신은 당신이 fgets을 사용하는 경우 입력의 라인을 읽는 것을 할 필요가 없습니다 scanf 대신 마지막 행에서 일부 입력을 읽습니다.

fgets N '\'sscanf (입력 문자열을 파싱) 버퍼 오버런으로부터 안전 하였다 ("\ n '또는 파일의 마지막까지 입력을 읽고), 그리고 여분의 입력 라인 종단을 흡수 :

#include <stdio.h> 

int main (void) 
{ 
    int  input; 
    char buf[16] = ""; 

    fgets (buf, sizeof buf, stdin); 

    sscanf (buf, "%d", &input); 

    printf ("The input is %d.\n", input); 

    fflush (stdout); 

    getchar(); 

    return 0; 
} 
printf

플러싱 stdout은 일반적으로 터미널 IO 필요하지 않습니다 ,하지만 당신은 일반적으로 당신이 충돌 프로그램을 로그인 할 때 그냥 전에 가장 흥미로운 비트를 잃게됩니다 디스크 (에 배관하는 경우 일 수있다 당신이 플러시하지 않으면 충돌). fgets는 최대 읽고 하나만 getchar, 약간 어색한 입력과 같은 1234공간가 발생하지 않습니다 입력이 필요하므로 라인의 끝을 포함하여 버퍼에 남아있는 문자가없는

때문에 멈추지 않고 끝내는 프로그램.

그러나 대부분의 경우 콘솔 응용 프로그램을 실행 한 후 기다릴 필요가 없습니다. Linux 나 다른 유닉스 시스템에서는 일반적으로 콘솔을 열고 거기에서 프로그램을 실행 한 다음 제어를 쉘로 반환합니다. Windows에서 비주얼 스튜디오와 같은 IDE를 일반적으로 run the program and pause 그것 같이 사용 무언가 :

"C:\WINDOWS\system32\cmd.exe" /c ""...\ConsoleApplication1.exe" & pause" 

또는 당신은 cmd.exe를 열고 거기에서 그것을 실행하거나 PIF가 바로 가기로 실행할 수 있으며, 체크 박스를 설정할 수 있습니다 그것은 종료 할 때 콘솔을 닫지 않거나 실행하고 일시 중지하는 배치 파일을 만들 수 있습니다.

Windows에서 디버거를 사용하여 실행 중이며 중단 점을 설정하지 않은 경우 프로그램을 일시 중지해야합니다.

1

사용되지 않은 버퍼 입력 문제에 대한 순진한 해결책입니다. 당신의 교수는 문제를 인식하지만 제대로 해결하는 방법을 모르는 것 같습니다.

형식화 된 입력을 사용하는 경우 형식 지정자와 일치하는 문자 만 사용됩니다. 예를 들어 마지막 입력이 % D를 사용 진수 정수를 요청하는 경우 따라서, 당신은 콘솔에서 입력 할 수 있습니다

123<newline>

포맷 된 입력은 <newline> 버퍼 떠나 "123"을 소모합니다. getchar()과 같은 형식화되지 않은 입력은이를 소비하고 즉시 반환됩니다. 이것이 당신이 원하는 것이 아니기 때문에, 당신의 교수는 "또 다른 getchar() kludge를 추가하십시오"를 사용했습니다. 이것은 사용자가 예상 입력을 입력 한 경우에만 작동합니다. 손재주없는 타이피스트는 입력 할 수 있습니다 :

지금 처음 getchar가()가 'w'도착

123w<newline>

, 경우, 두 번째는 <newline>를 얻을, 당신은 그것을 구성하기 전에 프로그램을 종료하고, GUI 환경에서 종료 프로세스가 실행중인 창을 소유하면 OS가이를 종료합니다.이전 입력이 문자 인 경우

물론
while(getchar() != '\n') { /*do nothing*/} ; 
getchar() ; /* wait */ 

, 당신이 이미 <newline> 아니었다 확인해야합니다 :

보다 강력한 솔루션은 반복적으로 발견되는 <newline>까지 getchar가()를 호출하는 것입니다

while(ch != '\n' && getchar() != '\n') { /*do nothing*/} ; 
getchar() ; /* wait */ 

오히려 단지 '기다려'입력 호출 전에 마지막 플러시 루프 바꾸어보다 그것을 필요 모든 입력 후 버퍼 플러시를 수행하는 것이 좋다. 그게 당신이 필요로하는 곳이고 그것이 코딩되어야하는 곳이기 때문입니다. 필자는 필요한 입력 유형에 대한 래퍼 함수를 ​​작성하는 경향이 있습니다.

+0

설명은 적절하지만 해결책은 강력하지 않습니다. 또한 'EOF'를 확인해야합니다. 그렇지 않으면 파일의 조기 종료로 무한 루프가 발생합니다. – chqrlie

+0

@chqrlie : 8 년 밖에 걸리지 않습니다! – Clifford

관련 문제