Programming Language/C언어 기본문법

[C언어] 문자열 입력 함수

lxvxxu 2024. 6. 15. 18:16

[C언어] 문자열 입력 함수

Contents

- 입력 함수의 정의
1. scanf()
2. gets(), getchar()
3. fgets()
4. 버퍼 오버플로우

 

 

구분 문자, 서식, 문자열, 버퍼, 버퍼 포인터


입력 함수란?

여러 종류의 데이터다양한 서식에 맞춰 입력받을 수 있도록 하는 함수를 의미

<stdio.h> 헤더파일에 해당 함수들이 포함되어 있다.

 

#include <stdio.h>

 


1. scanf()

- C언어 표준 입력 함수 중 가장 많이 사용된다.(대표적인 입력 함수)

 

scanf("%s", name);

 

- f: formmatted의 약자. 서식화된 입력을 받는다는 의미
- 입력받은 Data를 어떤 서식으로 변환할지 서식 지정자(format specifier, %s 등)를 통해 직접 지정 가능하다.

서식 예시
%02d, %d:%d, %.4d


- Visual Studio에서 scanf() 대신 scanf_s()로 쓰기도 한다.

 


가장 먼저 대표적인 입력 함수로는 scanf()가 있습니다.
scanf()의 'f'는 'formmatted'의 약자로, 서식화된 입력을 받는다는 의미입니다.
'서식화된 입력을 받는다'고 했는데 입력을 서식화하는 주체는 바로 프로그래머로
입력받은 Data를 어떤 서식으로 변환할지 서식 지정자(format specifier)를 통해 직접 지정이 가능합니다.

 

 

Visual Stduio에서 scanf() 오류 발생 시 해결 법

#define _CRT_SECURE_NO_WARNINGS

https://bymakers.tistory.com/6


2. gets(), getchar()함수

scanf() 함수와 비슷하지만 문자형을 위해 새롭게 개발된 함수이다.

띄어쓰기가 포함된 문자를 입력받을 수 있다.

 

2-1. gets()

gets(name);

 

엔터로 입력을 종료할 때 개행 문자(\n)를 해당 변수에 저장하지는 않으나, 키보드 버퍼에는 저장한다.

 

2-2. getchar()

엔터로 입력을 종료할 때 키보드 버퍼에 저장된 개행 문자(\n)를 없애준다.

 


scanf()와 비슷하지만 문자형을 위해 새롭게 개발된 함수가 있는데요. 그건 바로 gets()와 getchar()입니다.
scanf()에서는 띄어쓰기가 입력되면 입력을 종료되었는데
gets()와 getchar()을 통해서는 띄어쓰기도 문자열 내 저장이 가능합니다.
scanf()는 띄어쓰기, Enter를 통해서 입력 종료가 가능하고
gets()와 getchar()는 Enter를 통해서 입력 종료가 가능합니다. 이 때 두 함수 모두 개행 문자를 해당 변수에 저장하지 않습니다.
getchar()함수는 추가적으로 키보드 버퍼에 남아 있는 개행 문자를 제거해주는 기능도 있습니다.

 

 


3. fgets()

매개변수가 3개

fgets(문자열이 저장될 포인터, 입력받을 문자열의 길이, 입력받을 스트림)

 

fgets(name, 100, stdin)


- 개행 문자까지 읽는다. 개행 문자까지 저장한다.
- '100'을 입력했다면 마지막 '\0'(null 문자)를 저장할 공간을 제외하고 최대 99 길이의 문자열을 입력받을 수 있다.
- stdin은 표준 입력 장치의 스트림, 보통의 경우 키보드 버퍼를 뜻한다.

 


fgets()는 유일하게 1) 매개변수를 3개 입력받으며, 2) 입력받을 문자열의 길이를 입력받는 입력 함수입니다.
gets(), getchar()와 달리 fgets()는 띄어쓰기뿐 아니라 개행 문자도 저장합니다.
버퍼 오버플로우를 방지할 수 있는 함수이기도 합니다.

 


★ 만약 값을 저장한 공간 이상의 길이를 지닌 문자열이 입력되었다면 어떻게 반응할까?

 

gets()의 경우

저장할 수 있는 최대 공간( 할당 받은 메모리 )인 100을 넘어서까지 저장이 계속된다.
이를 '버퍼 오버플로'라고 하며 할당 받은 메모리의 범위를 넘어선다.
즉각적인 문제를 일으킬 가능성은 낮으나 위험성이 있다.

현업에서 많은 오류를 일으키기도 했다.


이러한 문제로 인해 수많은 프로그래머들이 표준에서 gets()를 삭제할 것을 권유해
C 표준을 만드는 위원회에서는 이를 인정하여

C99 표준에서는 이미 쓰여진 Program과의 호환성을 위해 표준에서 제외하지는 않았지만 사용 금지를 권했고,

최신 표준인 C11에서는 아예 제외되었다.

-> 대체함수로 gets_s()와 fgets()가 있다.

gets_s()는 C++에서만 사용이 가능하다.

 

fgets()의 경우

개행 문자를 만나거나 (n-1) 길이만큼의 문자열 길이만 읽어들인다.
따라서 99개의 문자만 읽어들이고
남은 값들은 다음 입력 함수로 넘긴다. "

 


 

함수 scanf(), scanf_s() gets() getchar() fgets()
정의 - 서식화된 입력을 받음
- 가장 많이 쓰이는 함수(대표 함수)
- 입력 받을 데이터의 서식을 지정 가능
- 버퍼 오버플로우 O fflush (stdin) 필요
키보드 버퍼에 존재하는 data 중에서 버퍼 포인터가 위치한 곳으로부터 1byte 분량을 꺼내오고 버퍼 포인터를 1byte만큼 이동시키는 함수이다.
- 매개변수 3개
- 버퍼 오버플로우 X
사용 예시 scanf("%s", name);
scanf_s("%s", name);
gets(name); getchar(name); fgets(name ,100, stdin);
입력 띄어쓰기 이전 or Enter 이전까지 띄어쓰기까지.
Enter도 가져오긴 하는데 \0으로 바꿔버림
Enter 이전까지. 띄어쓰기+Enter까지
구분 문자 - 공백문자(space, 띄어쓰기)
- 개행문자(Enter, \n)
- Enter - 개행문자(Enter, \n) - 개행문자(Enter, \n)
\0
(null 문자)
공백(space) 입력 시 \0 붙여줌.
Enter 입력 시 Enter 전까지 가져오고 마지막에 \0 가져옴?
Enter 입력 시 \0로 바꾸어 저장   Enter 입력 시 추가로 \0를 붙여줌
버퍼 \n을 버퍼에 남기고 간다.
=> 다음 입력함수에서 가져올 수 있다.
\n을 버퍼에 남기고 간다. 버퍼에 남겨진 \n을 제거해준다. \n까지 변수에 저장한다. 버퍼에 남는 문자 X

 

문자열을 키보드로 입력할 때 문자열이 바로 변수에 들어가는 것이 아니라 버퍼에 먼저 들어가게 된다.

버퍼에 입력된 문자열을 함수에 따라서 다른 방식으로 가져와 변수에 저장하게 되는 것이다.

하나의 프로그램에서 여러가지 입력함수를 이용해 문자열을 입력받으면 문제가 발생할 수 있으므로 혼동을 조심하자.

 

fflush();

키보드 버퍼를 모두 비워주는 함수다.

 


참고 링크

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

https://how-can-i.tistory.com/15

https://wndproc.tistory.com/entry/C-%EC%9E%85%EB%A0%A5%ED%95%A8%EC%88%98-scanf-gets-fgets-%ED%95%A8%EC%88%98-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%9E%85%EB%A0%A5%EC%8B%9C-%EC%B0%A8%EC%9D%B4%EC%A0%90

https://no-more-assignment.tistory.com/197#2

 


추가 자료 조사 예정

* 버퍼
* null 문자 - 문자열

* C언어 표준 



 

※ 틀린 정보가 있거나 보완이 필요한 내용이 있다면 댓글로 알려주세요.