Programming Language/C언어 기본문법

[C언어] 입출력 함수

lxvxxu 2024. 7. 10. 00:15
< 입력함수 >
버퍼를 사용하는지 안하는지
버퍼 사용 시 해결법은 모두 while(~)인지?
입력 구분 문자는 무엇인지(space, Enter 키 등)

 

※ 요약

입력함수

- scanf(): space, Enter 안 읽음. 버퍼 사용 O
- getchar(): 버퍼링 사용

※ scanf()와 getchar() 함수는 같은 버퍼를 사용하며 입력 데이터를 공유한다.
따라서 앞서 실행한 입력 함수가 버퍼에 남겨둔 데이터를 그 이후에 수행하는 함수가 잘못 가져갈 가능성이 있다.
=> 버퍼에 남아 있는 불필요한 데이터는 미리 제거하는 것이 좋다.
fflush(stdin); 은 잘못된 사용법이므로
while(getchar() != '\n'); 을 이용하여 버퍼에 남아 있는 개행문자를 제거한다.


출력함수
- getch(): 버퍼링 사용X
- gets(): Enter키를 NULL 문자로 바꿈.

- puts(): 문자열 끝에 자동으로 \n 붙임

 



+)
stdin : 입력 버퍼의 이름
stout : 출력 버퍼의 이름
printf()나 putchar()과 같은 표준출력 함수들이 공유한다.

fflush(stout);
위 코드는 버퍼의 내용을 지우는 것이 아니라 즉시 모니터로 출력한다.


 


Buffer

입출력을 하는 경우 데이터는 버퍼에 임시 저장되었다가
적정량이 모이면 한꺼번에 전송됨.
동영상을 재생할 때 Buffering과 같은 뜻임.

왜 이러는 걸까?
시스템에서 입출력은 중요도가 낮고 많은 노력이 들어감.
효율적으로 처리하기 위해 사용.

하지만 중요도가 높은, 즉시 처리해야 할 필요가 있는 입출력이 있을 수가 있음.
이 때 사용하는 함수가 fflush() 함수이다.

 


입력함수

scanf() - 버퍼 O

scanf()는 C 컴파일러와 함께 기본적으로 제공되는 함수이다.

 

※ scanf()는 사용자가 Enter, space가 나오면 값을 입력받는 것을 중지하므로,

   Enter, space 키는 scanf()로 입력받을 수 없다.

   또한, 한 번에 하나의 단어만을 읽을 수 있다.

※ %c, %d 등의 앞에 여분의 스페이스를 추가하는 것은

    숫자와 문자를 구별하여 입력받을 때 도움이 되므로 좋은 습관이다.

※ 이스케이프 시퀀스를 사용하지 말 것.

 

※ 앰퍼샌드 규칙의 예외

%s를 사용해서 문자 배열에 문자열을 입력 받을 때에는 앰퍼샌드를 사용하지 않아야 한다.

 

scanf()의 문제점

scanf()는 사용하기 쉬운 함수는 아니다. 사용자가 정확하게 입력하지 못하는 경우가 多

 

scanf()의 장점

scanf()를 사용하면 사용자에게 강제적으로 어떤 문자를 입력하게 할 수 있다.

사용자가 scanf()가 요구하는 문자를 함께 입력하지 않는다면 프로그램이 올바르게 동작하지 않는다.


getchar() - 버퍼 O

getchar() 함수는 키보드에서 입력된 문자를 반환한다.

 

* 반환한다

  함수가 호출되어서 돌아올 때 우리에게 어떤 값을 전달한다.

 

※ 줄바꿈 문자를 이용하여 버퍼에 남아 있는 Enter 키를 삭제한다.

버퍼는 엔터키를 누를 때까지 프로그램으로 전송되지 않다가, 엔터키를 누르면 한 번에 하나씩 문자를 전송한다.

1) 사용자가 입력을 잘못했어도 백스페이스키를 눌러서 수정할 수 있다.

   엔터키를 누르지 않는 한 언제든 수정이 가능하다.

2) 엔터키를 삭제하지 않으면 엔터키가 버퍼에 남아 있다.

    => 따라서 getchar() 함수를 이용함으로써 버퍼에 남아 있는 엔터키를 삭제해야 한다.

 

getch() - 버퍼 X (속도 ↑)

함수 getch()를 사용하면 getchar()처럼 엔터키 문제를 발생하지 않는다. getch()는 버퍼링을 사용하지 않기 때문이다.

 

* 버퍼링을 사용하지 않는다.

  엔터키를 기다리지 않고 사용자가 입력하는 문자를 바로 가져온다.

  그러나 입력하는 문자를 바로 가져오기 때문에 사용자가 잘못된 입력을 수정하기 위하여 백스페이스키를 사용할 수 없다.

  엔터키를 기다릴 필요가 없기 때문에 getchar()보다 조금 빠르다.

 

※ echo

   입력되고 있는 문자를 화면에 표시하는 것

   getch()는 getchar()처럼 입력된 문자를 화면에 echo하지 않는다.

   따라서 getch() 이후 putch()를 호출하여 사용자가 입력된 글자를 보게 만들어야 한다.

 

gets() 

gets()는 키보드에서 입력된 문자들을 문자열로 변환하기 위하여 엔터키 → NULL문자로 바꾼다.

※ scanf()보다 gets()를 사용하는 가장 중요한 이유는

   사용자에게서 스페이스를 포함하는 완전한 한 줄의 문자열을 입력받을 수 있다는 점이다.

 

※ BOF(버퍼 오버플로우) 현상이 발생하여 프로그램에 치명적인 문제를 일으킬 수 있다.

 

fgets()

인자가 3개! 배열의 길이를 인자로 줄 수 있기 때문에 BOF 현상을 방지할 수 있다.
fgets(str, sizeof(str), stdin);

 



출력함수

printf()

 

putchar()

 

putch()

 

puts()

puts()는 출력하는 문자열의 끝에 자동으로 줄바꿈 문자를 붙인다.

 

fputs()

fputs("안뇽허삽나까", stdout);

 

 


stream

표준 입력 스트림 "stdin"
키보드 - 프로그램을 연결

표준 출력 스트림 "stdout"
프로그램 - 모니터를 연결

※ 위와 같은 표준 입출력 스트림들은 프로그램 실행 시 자동으로 생성되고 종료 시 자동으로 소멸된다.


오류 출력용 "표준 에러 스트림" "stderr"

음? 작성자가 공부하다 때려친 듯
https://kwonzales.tistory.com/11

 

[C언어] 입력, 출력과 스트림 - stdin, stdout

입출력에 관해서.. 입력이란, 실행중이 프로그램을 데이터로 받아들이는 것을 뜻합니다. C언어에서의 대표적인 입력은 키보드입니다. 그것을 위해 사용하는 대표적인 함수는 scanf 입니다. 또한

kwonzales.tistory.com

 

stdin

dd

 

stout

dddd


fflush( stdin )

int fflush(FILE *stream)
fflush(stdin)
" C 라이브러리 함수로서 출력 버퍼를 지운다."
성공 시 0을, 실패 시 EOF를 리턴한다.
FILE 포인터인 stream을 매개변수(인자)로 받는다.
 - 입력 stream이 전달되면 입력 버퍼 안에 있는 데이터를 모두 삭제한다.
 - 출력 stream이 전달되면 출력 버퍼 안에 있는 데이터를 즉시 출력한다.

입력 버퍼(X) 출력 버퍼(O)를 비운다.
우리는 입력 버퍼를 비워야 한다.
Why?
문자 or 문자열 입력 후 Enter를 누름으로써 의도하지 않았던 줄바꿈 문자가 Program의 입력 버퍼로 들어갔기 때문이다.

 


EOF

Ctrl+Z

'End of File'의 약자로 Ctrl+z를 누르면 EOF가 반환된다.

-1

 

 

 


 

참고

https://8ublictip.tistory.com/6 

https://kwonzales.tistory.com/9

 

 

 

 

#include <stdio.h>

int main(void){
	char perID[7];
	char name[10];
    
	fputs("주민번호 앞 6자리를 입력하세요.\n입력: ", stdout);
	fgets(perID, sizeof(perID), stdin);
    
	fflush(stdin)
    
	fputs("이름을 입력하세요.\n입력: ", stdout);
	fgets(name, sizeof(name), stdin);
    
	printf("주민번호 앞자리 : %s\n", perID);
	printf("이름 : %s\n", name);
    
	return 0;
}