[C 언어] 17. 입력함수(scanf, getchar) 이해

프로그래밍/C언어|2022. 4. 11. 15:38

2022.04.11 - [프로그래밍/C언어] - [C 언어] 16. 메모리동적할당

 

[C 언어] 16. 메모리동적할당

2022.04.11 - [프로그래밍/C언어] - [C 언어] 15. 함수포인터 [C 언어] 15. 함수포인터 2022.04.11 - [프로그래밍/C언어] - [C 언어] 14. 응용포인터와 주소연산자 [C 언어] 14. 응용포인터와 주소연산자 2022.04...

dlwlxo3819.tistory.com

 

====================== < 전체 소스코드 > ======================

 

#include<stdio.h>

// ========================================= 함수 선언부 ====================================================================

void my_gets(char* str, int size);	//	[ 입력받은 문자열을 저장하는 함수 ]

// ========================================= main 함수 ====================================================================

int main(void)
{
	printf("\n------------------- < 1) scanf를 통한 버퍼 이해 > ---------------------------------------------\n\n");
	// 모든 키보드로 받는 값은 일단 버퍼에 저장되나음 이 저장된 값이 함수등에 의해 변수에 입력되는 형태를 띈다.

	char ch_1_1, ch_1_2;

	//for (int i = 0; i < 3; i++)				// 3회 반복
	//{
	//	scanf("%c", & ch_1_1);				// 문자입력
	//	printf("%c", ch_1_1);				// 입력된 문자
	//}
	// !!! scanf의 원리는 버퍼가 비어있는 경우 키보드의 입력을 받아 입력받은값을 버퍼에 저장하고 저장한 값을 자료형에 맞게(크기[byte] 기준) 들고와서(복사아님!) 변수의 주소에 저장

	// !!! 위와 같은경우 실행후, 입력창에 'tiger'을 입력하면 버퍼에 tiger가 입력되고 이 버퍼에서 for문에 따라 ch_1_1에 한글자씩 3번버퍼에서 뽑아내서 저장한다.
	//	즉, printf문에 의해 tig가 출력되고 버퍼에는 여전히 er이 남아있다.
	

	while (1)							// 개행문자 입력받을때까지 입력받고 출력하기를 반복
	{
		scanf("%c", &ch_1_2);
		if (ch_1_2 == '\n') break;
		printf("%c", ch_1_2);
	}

	// 맨위의 3회반복때 키보드 입력의 끝을 표시하기위해 ENTER(개행문자)를 입력했고 이게 버퍼에 남아있기 때문에 버퍼는 비어있지 않다!
	// 즉, while문내의 if문에 의해 바로 break된다.

	// 주석처리등을 통해 위의 while문 만을 단독 실행할 경우 ENTER,\n을 입력받기 전까지 공백,탭을 포함해 모든 키보드 입력이 버퍼에 저장(마지막에 입력한 ENTER도 저장됨)된 다음
	// scanf에 의해 한글자씩 옮겨져(복사아님) ch_1_2에 저장되고 출력되고 다음글자가 입력되고(덮어씌움)를 반복
	// 

	printf("\n------------------- < 2) scanf함수 반환값 활용 > ---------------------------------------------\n\n");

	//	운영체제나 시스템 버전등에 따라 scnaf의 반환값을 -1로 만드는 방법이 다른데 
	//	'윈도우 10'인 경우	:	'ctrl + z' 누르고 'ENTER'를 누른다음 다시 'ctrl + z'를 눌러야 된다
	//	'리눅스'의 경우		:	'ctrl + d' 를 루르면 된다
	//	-1을 반환하는 이유는 프로그램 종료를 위함이다.

	int res_2;
	char ch_2;

	while (1)
	{
		res_2 = scanf("%c", &ch_2);			// 문자입력 ( 마지막의 ENTER 까지 모두 입력된다 )
		if (res_2 == EOF) break;			// stdio.h에는 EOF가 -1 로 상수가 이미 입력되어있어 쓸수 있다.
		printf("%d ", ch_2);					// 입력된 문자의 아스키코드값 출력 ( 마지막에 입력된 ENTER( = 10 ) 도 전부 출력된다. )
	}

	printf("\n------------------- < 3) getchar 함수를 이용한 문자열 입력 > ---------------------------------------------\n\n");

	char str_3[7];

	my_gets(str_3, sizeof(str_3));
	printf("입력한 문자열 : %s\n", str_3);


	printf("\n------------------- < 4) 입력버퍼 지우기 > ---------------------------------------------\n\n");

	// 조건등에 의해 scanf가 입력받은 값을 다 가져가지 못할경우( 보통 enter가 맨뒤에 남아있다) 다음 scanf가 엔터를 바로 가져가서 오류발생(프로그램상의 오류)
	// 이를 대비하여 버퍼를 초기화 해야한다.

	int num_4, grade_4;

	printf("학번 입력 : ");
	scanf("%d", &num_4);
	getchar();										// !! 버퍼초기화 !!

	printf("학점입력 : ");
	grade_4 = getchar();
	printf("학번 : %d, 학점 : %c", num_4, grade_4);

	//	버퍼초기화 없이 위의 내용을 실행하면 한번입력하여 num_4에 입력한 학점이 저장된 다음 마지막에 입력한 ENTER가 버퍼에 남아있고
	//	이를 grade_4가 getchar()를 이용해 가져가 바로 끝나버린다.

	// * 다양한 버퍼 초기화 방법 *  - 자세한 내용은  18번을 볼것
	//getchar();					// 버퍼에서 하나의 문자를 읽어서 반환, 반환문자는 버림
	//scanf("%*c");				// 버퍼에서 하나의 문자를 읽어서 버림, 변수는 필요없음 (scnaf("%*c") 는 버퍼를 비우는 약속(일종의 아스키코드종류)이다) 
	//fgetc(stdin);				// 버퍼에서 하나의 문자를 읽어서 반환, 반환문자는 버림 ( !!! fgets가 아니라 fgetc임을 주의 !!!! )

	return 0;
}



// ========================================= 함수 정의부 ====================================================================

//	3) getchar 함수를 이용한 문자열 입력 함수정의
void my_gets(char* str, int size)	//	[ 입력받은 문자열을 저장하는 함수 ]
{
	int ch;
	int i = 0;

	ch = getchar();								// 첫번째 문자 입력
	while ((ch != '\n') && (i < size - 1))		// 배열의 크기만큼 입력
	{
		str[i] = ch;			// 입력한 문자를 배열에 저장
		i++;					// 첨자증가
		ch = getchar();			// 새로운 문자입력
	}
	str[i] = '\0';				// 입력된 문자열의 끝에 널문자 삽입
}

댓글()