본문 바로가기

별걸다하는 IT/프로그래밍언어

[C/C++강좌] getc 함수, fgetc 함수, getchar함수 차이가 궁금해요! putc VS fputc VS putchar ?!

반응형

[C /  C++ 완전정복 목차]

안녕하세요. 양햄찌 주인장입니다.

오늘은 늦은 시간이라 빠르고 간단한 포스팅을 후다닥 올려보려고 해요.

오늘 포스팅의 주인공은 하나의 글자를 입력받거나 출력받는 getc / fgetc / getchar / putc / fputc / putchar 입니다.

getc / fgetc / getchar 그리고 putc / fputc / putchar 비교

fgetc 함수를 처음 보시는 분은 아래 포스팅에 fgetc & fgets 함수에 대해 자세히 설명해놓았으니 먼저 읽고 오시기를 권해드립니다.

▼ fgetc함수 fgets 함수 사용법: https://jhnyang.tistory.com/199

 

[C/C++] 파일 입출력 함수, 파일 읽는 함수 fgets & fgetc 함수 알아보기, 파일 문자열 컨트롤 함수 stdio

[C/ C++ 포스팅 링크 모음 목차] 안녕하세요! 저번에 파일 입출력의 시작을 알리는 스트림에 대해서 알아봤어요 ㅎㅎ 지난번 포스팅이 궁금하다면 아래 링크를 참고하세요 [C언어] 파일입출력 1편-

jhnyang.tistory.com

getc, fgetc, getchar 함수 프로토타입

■ int getc ( FILE * stream );

 int fgetc ( FILE * stream );

 int getchar ( void );

일단 기본적으로 셋 다 모두 하나의 char 타입 문자를 받는 함수입니다. 세 함수 모두 읽어들인 문자를 아스키코드값으로 리턴해줘요.

putc, fputc, putchar 함수 프로토타입

■ int putc ( int character, FILE * stream );

■ int fputc ( int character, FILE * stream );

■ int putchar ( int character );

위의 get류 함수들과 마찬가지로 요 put관련 함수들은 char 타입 하나의 문자를 쓰는 역할을 해요.

1. getc VS fgetc / putc VS fputc

먼저 getc와 fgetc에 대해 살펴볼게요 (입력이 아닌 출력에 사용되는 putc와 fputc간의 차이도 이와 동일합니다.)

문득 이름만 봤을 때에는 fgetc는 파일입출력에서 사용하는 getc함수 같고 getc는 표준입출력에서 사용하는 getc함수 같잖아요? 그런데 사용법을 살펴보면 둘 다 스트림 정보인 파일구조체를 인자로 받고 있습니다. 프로토타입이 함수명 제외하곤 동일해요!

#include <stdio.h>
#include <string.h>
int main()
{
	printf("getc: %c\n", getc(stdin));
	printf("fgetc: %c\n", fgetc(stdin));	
	return 0;
}

즉 사용방법은 서로 차이가 없다! fgetc도, getc도 파일입출력이 가능하단 이야기가 되죠. 

 

이번엔 putc/ fputc를 써서 출력해볼게요

#include <stdio.h>
#include <string.h>
int main()
{
	putc(getc(stdin), stdout);
	fputc(fgetc(stdin), stdout);

	return 0;
}

출력에 사용되는 표준스트림은 stdout이니까 stdout을 넣어줍시다.

putc /fputc 또한 별 차이 없이 동일하게 출력되었어요

 

그럼 getc vs fgetc 그리고 putc vs fputc간의 차이가 뭘까요. 

ISO문서에서 발췌

최신 2018 ISO문서에 보면 이렇게 명시되어 있습니다.

"getc함수는 매크로로 구현되어 있고 stream을 한 번 이상 판단하는 점만 제외하면 기본적으로 getc함수는 fgetc와 동일하다. getc함수는 매크로로 구현되어 있어 부작용이 있을 수 있기 때문에 인자가 수식으로 오면 안된다. "

--> getc함수는 매크로 형태로 구현, fgetc는 함수 구현.

putc 함수는 매크로 구현, fputc는 함수 구현

 

인자가 수식으로 오면 안된다는건 

  char c = getc(*p++);

이런식으로 사용하면 곤란해질 수 있다는걸 의미해요.

 

위의 설명처럼 getc, putc는 매크로로 구현되어 있기 때문에 fgetc, fputc함수보다 속도가 빠르다는 장점이 있습니다.  

하지만 fgetc, fputc는 매크로가 아닌 함수로 구현되어 있기 때문에 다른 함수의 인자로 넘겨줄 수 있어요. 즉 함수포인터로써 활용이 가능한거죠 ㅎㅎ

2. getc VS getchar / putc VS putchar

getc, putc 함수는 스트림을 인자로 받지만 getchar, putchar 스트림 인자를 받지 않아요! 그냥 항상 getchar(), putchar(c) 이렇게만 사용해주면 됩니다.

요 경우 차이점은 단순해요.

ISO문서 발췌

getchar 함수는 getc함수를 표준입력 스트림으로 사용한 것과 동일합니다.

putchar 함수는 putc함수를 표준출력 스트림으로 사용한 것과 동일해요.

#include <stdio.h>
#include <string.h>
int main()
{
	char c = 'A';
	printf("getc: %c\n", getc(stdin));
	printf("fgetc: %c\n", getchar());

	printf("result of putc & putchar: ");
	putc(c, stdout);
	putchar(c);
	return 0;
}

getc(stdin)이 결국 getchar(), putc(c, stdout)이 putchar(c)예요.

결과창

파일에서 입력받는거 말고, 우리 그냥 테스트할 때 쓰듯이 키보드로부터 입력을 받고 싶은데 그럴 때마다 매번 getc(stdin), putc(stdout) 이렇게 써주는게 귀찮잖아요. 그럴땐 getchar 함수, putchar 함수 사용하시면 됩니다. 

getchar()가 결국 getc(stdin)으로 매크로 되어있다.

getchar()와 getc(stdin) 특징

■ 헤더 파일 stdio.h에 존재한다.

 키보드버퍼 (keyboard buffer)로부터 입력을 받는다.

 엔터 값도 '\n'글자로 키보드 버퍼에 저장한다.

 space또한 공백으로 입력받을 수 있다.

 하나의 문자만 입력받기 때문에 두 자리를 못받는다, 12를 입력하면 1과 2를 따로 인식한다.

 버퍼로부터 입력받기 때문에 버퍼비움(ex fflush(stdin))이 필요하다.

■ 엔터가 입력될 때까지 키보드 입력값들을 계속해서 키보드 버퍼에 저장한다.

■ 키보드 버퍼에 존재하는 data 중에서 버퍼 포인터가 위치한 곳으로부터 1바이트 분량을 꺼내오고 버퍼 포인터를 1바이트만큼 이동시키는 함수이다.

 

오늘은 간단하게 비스무리해보이는 getc, fgetc, getchar 그리고 putc, fputc, putchar 에 대해 알아보았어요.

도움이 되셨다면 공감/댓글/광고보답 중 하나로 마음을 표현해주시는건 어떤가요?

오늘도 고생많으셨습니다 :) 

반응형