티스토리 뷰

C언어

C언어 표준 입력 함수

블로그 강승 2021. 3. 15. 18:00

C언어 표준 입력함수

C언어 표준 입력함수에 대해서 Do it! C언어 입문(저자:김성엽) 이란 책을 통해 공부했으며, 책의 카테고리를 바탕으로 필자가 이해한 내용을 요약한 글이다. 내용이 궁금하거나 찾아야 할 내용이 있으면, 필자가 정리한 글을 다시 보면서 복습하기위해 작성했다. 바로 아래에서 글을 확인하도록 하자.

 

표준 입력 장치

컴퓨터에는 많은 입력 장치가 있다. 마이크, 마우스, 키보드, 조이스틱 등이 있겠지만 이 중에서 시스템이 가장 기본으로 생각하는 장치를 표준 입력 장치라고 한다. 컴퓨터는 키보드이다.

 

표준 입력 함수의 동작 원리

표준 입력 함수를 선언하고나서 입력장치로 입력을 하면 바로바로 실행이 되는게 아니라 임시로 입력 값들을 저장해 두었다가 표준 입력 장치인 키보드의 '엔터'를 눌러야 표준 입력 함수가 처리됨.

 

입력 값을 임시로 저장하는 표준 입력 버퍼

'표준 입력 버퍼' 혹은 '입력 버퍼' 운영체제가 제공함. 특정 키('엔터')를 누를 때까지 사용자가 누른 입력을 임시로 저장하는 메모리임. 하지만 입력 버퍼에 있는 내용을 전부 사용하지 않고 버퍼에 남아있다면 다음 표준 입력 함수를 만났을 때 뜻하지 않게 입력 버퍼에 남아있던 게 선언될 수 있음.

※표준 입력 버퍼에 정보가 남아있다면 표준입력 함수를 만났을 때 그 정보로 바로 실행되고, 정보가 없다면 입력을 계속 받다가 '엔터'가 눌러질 때 표준 입력 함수가 실행됨.

 

rewind 함수

입력 버퍼에 남아있는 정보를 모두 지우는 함수임.

rewind(stdin);
/* stdin은 standard input 의 약자고 포인터임.
stdin 포인터를 사용하면 장치에서 입력한 값을 얻을 수 있음 */

 

stdio.h

#include 전처리기로 습관적으로 참조하는 stdio.h(standard input output header)은 표준 입력 함수가 정의 되어있음.

 

getchar 함수

int 형식으로 데이터를 반환함. 하지만 char 로도 받아도 됨.(입력 문자들 대부분 1바이트이므로)

#include <stdio.h>
void main()
{
int input_data;

input_data = getchar(); /* 문자 하나를 출력해줌. a를 치고 엔터를 첬다고 가정 */
printf("first input : %c\n", input_data); /* input_data에 'a'가 대입 돼 있음 */
input_data = getchar(); /* 기억 버퍼에 '엔터'가 남아있어서 그대로 '엔터'가 input_data에 대입됨 */
printf("second input : %c\n", input_data);
}
/* 결과화면
a
frist input : a
second input : 
*/

/* '엔터'를 대입하고 %c로 출력하면 빈화면이 나옴. 직접 코딩으로 확인해길 */

 

getc 함수

input_data=getc(stdin); getc 함수는 문자뿐만 아니라 파일에서 1바이트씩 정보를 읽어서 사용자에게 전달해줄 수도 있음. 매개변수 자리에 stdin을 입력하면 문자를 입력받고, 파일의 포인터를 입력하면 파일을 읽어줌. getc(stdin)을 일일이 쓰기 힘들어서 여기에서 getchar() 함수가 나온 거임.

 

문자열을 입력받는 gets 함수

한 번에 여러 개의 문자를 입력받을 수 있고, 엔터를 누르면 엔터 아래에 있는 거 + 0(NULL)까지 입력됨(참고로 엔터는 입력 안됨). 그리고 매개변수로 문자열을 저장할 변수의 시작 주소를 넘겨줘야 함.

char input_string[10];
gets(input_string);
/* gets(&input_string[0]); 라고 해도 무방하지만
배열은 이름만써도 시작주소를 보내줌 */

참고로 엔터키가 배열 안으로 입력은 안돼도, 버퍼에 남아있는 엔터키도 같이 처리해주기 때문에 버퍼에는 엔터가 남지 않음. 그리고 getchar()에서 봤던 대로 엔터를 입력하더라도 gets에서는 문자열을 다 입력했다는 신호로만 사용해서 고의로 엔터를 눌러도 엔터가 들어가진 않음.(엔터가 눌러진 시점에 0(NULL)이 들어감). gets() 함수를 사용하다가 의도치 않게 입력이 실패하면 gets() 함수는 NULL을 반환함. 입력에 성공하면 변수의 시작 주소를 반환함. 그래서 NULL이 반환됐을 경우에 어떻게 처리할지도 코딩을 해놔야 함.(※NULL은 stdio.h 파일에 선언되어 있어서 0으로 처리해도 됨. 하지만 프로그래머들이 대개 NULL을 '메모리 주소가 없음'으로 이해함.)

#defind NULL ((void *)0)
#inlcude <stdio.h>
void main()
{
char input_string[10];
if(gets(input_string)) printf("input : %s\n", input_string); /* 성고하면 변수의 시작주소를, 실패하면 NULL(0)을 반환함 */
else printf("input -> Canceled\n");
}

 

gets 함수가 정의 안돼 있으면 fgets 함수를 쓰면 됨

char input_string[10];
fgets(input_string,10,stdin);
/* 파일에서 데이터를 읽어 오는 함수지만, stdin을 입력하면 버퍼에서 정보를 받음.
10은 저장할 메모리의 최대 크기를 나타냄. input_string의 최대 크기가 10이란 뜻임.
그리고 이 함수는 '\n' 값도 값에 저장되고 그 이후에 0(Null)이 붙음.
'\n'은 아스키코드로 10번이고 문자로는 \n 임 */

 

문자열을 입력받을 때 키 입력 횟수 제한

fgets 함수를 이용하면 제한할 수 있긴 함. 그리고 다른 타사에서 대안이 되는 함수나 기술을 제공하기도 함. 하지만 실력을 늘리려면 본인이 기본 함수로도 할 줄 알아야 함.

#include <stdio.h>

int GetMyString(char buffer[], int limit) /* 길이 제한해주면서 문자열을 받는 함수 */
{
int i;
for(i=0; i<limit; i++){
buffer[i]=getchar(); /*문자열을 쫙 입력하고 엔터를 누르면 버퍼에서 다 기억하고 맨앞만 buffer[i]에 넣음*/
if(buffer[i]=='\n'){ /*버퍼에 저장된 마지막 엔터가 나오면 문자가 끝난거니, 0으로 바꿔주고 반환함*/
buffer[i]=0;
return 1; /*정상 처리 했을시 정수 1을 반환 */
}
}
buffer[i]=0; /* limt을 넘겼을시 해당자리에 NULL(0)을 넣고 정수 0을 반환 */
rewind(stdin);
return 0;
}

void main()
{
char temp[10];
int state;
state = GetMyString(temp,9);

if(state==1) printf("input : %s\n", temp);
else printf("input :%s ->out of range\n", temp);
}

 

문자열을 정수로 변환하기

gets함수로 숫자를 입력받으면 문자열로 인식하기 때문에 산술을 못함. 왜냐하면 '문자열'끼리는 산수가 안되기 때문임.하지만 문자끼리는 산수가 가능함.

'0' - '0' 48(아스키코드) - 48(아스키코드) 0 문자'0'이 숫자 0로 변환
'1' - '0' 49(아스키코드) - 48(아스키코드) 1 문자'1'이 숫자 1로 변환
'2' - '0' 50(아스키코드) - 48(아스키코드) 2 문자'2'가 숫자 2로 변환
#include <stdio.h>
void main()
{
int num = 0; count = 0;
char num_string[4] = "123";

while(num_string[count] != 0) { /* NULL(0)을 만나면 반복문 종료 */
num = num * 10 + (num_string[count] - '0'); /* 요소 0부터 차례로 올라가는데기존 값을 계속 10을 곱해주면서 자리수를 만들어 가고있음*/
count++;
}
printf(" %s -> %d\n",num_string,num);
}

/*출력화면 123 -> 123 
왼쪽 123은 문자열이고 오른쪽 123은 정수임 */

 

 

atoi 함수

atoi 함수는 stdlib.h 파일에 함수의 원형이 정의되어있음.

#include <stdio.h>
#include <stdli.h>
void main()
{
int first_num, second_num;
char first_string[16], second_string[16];

printf("input first number : ");
gets(first_string);
printf("input second number : ");
gets(secned_string);

frist_num=atoi(first_string); /* 문자열 -> 정수 */
frist_num=atoi(second_string); /*문자열 ->정수 */

printf("%d + %d = %d\n", first_num, second_num, first_num + second_num);
}
/* 결과 화면
input first number : 25       (엔터입력 하면 아랫줄이 생김)
input second number : 157      (엔터입력 하면 아랫줄이 생김)
25 + 157 = 182 */

 

scanf 함수

printf 함수와는 다르게 scnaf는 포인터의 주소를 받기 때문에 자료형이 반드시 일치해야 한다.

키워드 %d %hd %f %lf %c %s
입력 형식 정수(int,unsigned int) 정수(short int) 실수(float) 실수(double) 문자(char,unsigned char) 문자열(char *, char[])
#include <stdio.h>
void main()
{
int num1, num2, num3;
scanf("%o %d %x, &num1,&num2, &num3);
/* 8진수는 %o, 10진수는 %d, 16진수는 %x */
printf("input : %d, %d, %d \n", num1, num2, num3);
}
/* 결과화면 10 10 10 (엔터입력)
input : 8, 10, 16  */
int data;
scanf("%d",&data);
/* scnaf는 %d는 자료형을 int만 취급해서
data의 자료형이 반드시 int 여야함 */


글을 마음대로 배포하셔도 되지만, 출처(링크)는 반드시 남겨주시기 바랍니다.

'C언어' 카테고리의 다른 글

C언어 정적 메모리할당  (0) 2021.03.15
C언어 배열과 포인터  (0) 2021.03.15
C언어 포인터  (0) 2021.03.14
C언어 배열  (0) 2021.03.12
C언어 지역 변수/전역 변수  (0) 2021.03.12
댓글