`getchar()`는 사용자 입력을 어디에 저장합니까?
-
05-07-2019 - |
문제
나는 읽기 시작했다 "C 프로그래밍 언어" (K&R) 그리고 저는 그 부분에 대해 의문이 있습니다. getchar()
기능.
예를 들어 다음 코드는 다음과 같습니다.
#include <stdio.h>
main()
{
int c;
c = getchar();
putchar(c);
printf("\n");
}
타자 toomanychars
+ CTRL 키+디 (EOF)는 단지 t
.첫 등장 캐릭터인 만큼 기대되는 부분인 것 같아요.
하지만 다음 코드는 다음과 같습니다.
#include <stdio.h>
main()
{
int c;
while((c = getchar()) != EOF)
putchar(c);
}
타자 toomanychars
+ CTRL 키+디 (EOF) 인쇄 toomanychars
.
내 질문은 char 변수가 하나만 있는 경우 왜 이런 일이 발생합니까?나머지 문자는 어디에 저장되어 있나요?
편집하다:
답변해주신 모든 분들께 감사드립니다. 이제 이해가 시작됩니다.단 하나의 캐치 :
첫 번째 프로그램은 주어지면 종료됩니다. CTRL 키+디 두 번째는 전체 문자열을 인쇄한 다음 추가 사용자 입력을 기다립니다.왜 다른 문자열을 기다리고 첫 번째 문자열처럼 종료되지 않습니까?
해결책
입력 스트림을 파일처럼 처리합니다. 마치 "Toomanychars"텍스트가 포함 된 파일을 열고 한 번에 하나의 문자를 읽거나 출력 한 것처럼 보입니다.
첫 번째 예에서는 While 루프가 없으면 파일을 열고 첫 번째 문자를 읽은 다음 출력 한 것과 같습니다. 그러나 두 번째 예제는 파일 신호가 끝날 때까지 문자를 계속 읽습니다 (ctrl+D
귀하의 경우) 디스크의 파일에서 읽고있는 것처럼.
업데이트 된 질문에 대한 답변으로 어떤 운영 체제를 사용하고 있습니까? Windows XP 노트북에서 실행했는데 잘 작동했습니다. 내가 Enter를 때리면 지금까지 가지고있는 것을 인쇄하고 새 라인을 만들고 계속합니다. (그만큼 getchar()
Enter를 누르기 전까지는 기능이 반환되지 않습니다. 이는 입력 버퍼에 호출 될 때 아무것도 없을 때입니다). 내가 누를 때 CTRL+Z
(Windows의 EOF), 프로그램이 종료됩니다. Windows에서 EOF는 명령 프롬프트에서 EOF로 계산되도록 자체 라인에 있어야합니다. 이 동작이 Linux에서 모방되었는지 또는 실행중인 시스템이 있는지 모르겠습니다.
다른 팁
getchar
표준 입력에서 단일 문자를 가져옵니다.이 경우 키보드 버퍼입니다.
두 번째 예에서 getchar
기능은 a에 있습니다 while
직면 할 때까지 계속되는 루프 a EOF
, 따라서 입력이 비어있을 때까지 계속 루핑하고 문자를 검색하고 문자를 인쇄합니다.
연속적인 전화 getchar
입력에서 나오는 연속적인 문자를 얻을 수 있습니다.
아, 그리고이 질문을하는 것에 대해 기분이 나쁘지 않습니다. 나는이 문제를 처음 만났을 때 당황했습니다.
여기 뭔가가 버퍼링되어 있습니다.예를 들어putchar가 쓰는 stdout FILE*은 line.buffered일 수 있습니다.프로그램이 종료되거나 개행 문자를 만나면 FILE*이 fflush()로 처리되고 출력이 표시됩니다.
어떤 경우에는 보고 있는 실제 터미널이 개행 문자가 나올 때까지 또는 터미널 자체가 버퍼를 플러시하라는 지시를 받을 때까지 출력을 버퍼링할 수 있습니다. 이는 새 프롬프트를 표시하려고 하기 때문에 현재 포그라운드 프로그램이 종료되는 경우일 수 있습니다.
이제 여기서 실제 사례가 될 가능성이 있는 것은 입력이 버퍼링된다는 것입니다(출력 외에 :-)) 키를 누르면 터미널 창에 나타납니다.그러나 터미널은 해당 문자를 응용 프로그램에 보내지 않으며 Ctrl+D를 사용하여 입력이 끝나도록 지시할 때까지 버퍼링하며 개행도 가능합니다.여기 놀고 생각해 볼 수 있는 또 다른 버전이 있습니다.
int main() {
int c;
while((c = getchar()) != EOF) {
if(c != '\n')
putchar(c);
}
return 0;
}
프로그램에 문장을 입력하고 Enter를 누르십시오.(c! = ' n')가 입력, 출력 또는 둘 다에 어떤 식 으로든 버퍼링되어 있는지 확인할 수 있는지 여부를 언급하면 동일한 작업을 수행하십시오.위의 명령을 다음과 같이 실행하면 더욱 흥미로워집니다../mytest | ./mytest
(부담으로 CTRD+D는 문자도 아니고 EOF도 아니라는 점에 유의하세요.그러나 일부 시스템에서는 입력 스트림이 닫혀 스트림에서 읽으려고 시도하는 사람에게 EOF가 다시 발생합니다.)
첫 번째 프로그램은 하나의 캐릭터 만 읽고 인쇄하여 출구를 읽습니다. 두 번째 프로그램에는 루프가 있습니다. 그것은 한 번에 하나씩 문자를 계속 읽고 EOF 캐릭터를 읽을 때까지 인쇄합니다. 주어진 시간에 하나의 캐릭터 만 저장됩니다.
변수 만 사용하고 있습니다 c
한 번에 각 문자를 포함합니다.
첫 번째 숯을 표시 한 후t
) 사용 putchar(c)
, 당신은 가치를 잊어 버립니다 c
다음 문자를 할당하여o
) 변수에 c
, 이전 값 대체 (t
).
코드는 기능적으로 동일합니다
main(){
int c;
c = getchar();
while(c != EOF) {
putchar(c);
c = getchar();
}
}
이 버전을 이해하기 쉽다는 것을 알 수 있습니다. 조건부에 할당을 넣는 유일한 이유는 'c = getchar ()'를 두 번 입력하지 않아도됩니다.
업데이트 된 질문의 경우 첫 번째 예에서는 하나의 문자 만 읽습니다. 그것은 결코 EOF에 도달하지 않습니다. 이 프로그램은 Printf 명령을 완료 한 후에 할 일이 없기 때문에 종료됩니다. 그것은 단지 하나의 캐릭터를 읽습니다. 인쇄합니다. Newline에 넣습니다. 그리고 더 이상 할 일이 없으므로 종료됩니다. 둘 이상의 캐릭터를 읽지 않습니다.
반면, 두 번째 코드에서는 getchar와 putchar가 while 루프 안에 존재합니다. 이것에서, 프로그램은 문자에 도달 할 때까지 (^d)에 도달 할 때까지 문자를 하나씩 하나씩 읽습니다 (루프에 의해 만들어졌습니다). 이 시점에서 C! = EOF와 일치하며 조건이 충족되지 않기 때문에 루프에서 나옵니다. 이제 더 이상 실행할 진술이 없습니다. 따라서이 시점에서 프로그램이 종료됩니다.
도움이 되었기를 바랍니다.