[C 언어 fgets 함수 완전 해설] 안전한 문자열 입력과 버퍼 처리 베스트 프랙티스

1. 소개

fgets 함수는 C 언어에서 문자열을 안전하게 읽어오기 위한 표준 라이브러리 함수입니다. 기존의 gets 함수에 대체되는 안전한 방법으로 널리 사용되고 있습니다. 본 기사에서는 fgets 함수의 사용법과 그 장점 및 단점, 안전한 입력 처리 방법에 대해 자세히 설명합니다.

2. fgets 함수의 기본적인 사용법

2.1 fgets의 구문과 매개변수

fgets의 기본 구문은 다음과 같습니다。
char *fgets(char *str, int n, FILE *stream);
  • str: 입력된 문자열을 저장하는 버퍼
  • n: 읽어들일 최대 문자 수(버퍼 크기)
  • stream: 입력 스트림(보통 stdin)

2.2 샘플 코드 소개

다음은 fgets를 사용한 기본 예제입니다。
char buffer[50];
fgets(buffer, 50, stdin);
printf("입력된 문자열: %s", buffer);
이 코드는 사용자로부터 최대 49문자(끝의 널 문자를 포함하면 50문자)를 읽어들여 그 결과를 출력합니다。
侍エンジニア塾

3. fgets의 장점과 문제점

3.1 gets 함수에 비해 안전성

gets 함수는 버퍼 오버플로우를 일으킬 가능성이 있어 보안상의 위험이 높습니다. 반면, fgets 함수는 읽어들일 문자 수를 지정할 수 있어 버퍼 오버플로우를 방지합니다.

3.2 개행 문자 문제와 버퍼 처리

fgets는 입력 시 개행 문자도 포함해서 읽어들이기 때문에 의도하지 않은 개행이 포함될 수 있습니다. 또한, 버퍼 크기에 제한이 있어 입력이 이를 초과하면 스트림에 여분의 데이터가 남게 됩니다.

4. 안전한 입력 처리 방법

4.1 개행 문자 삭제 방법

fgets로 읽어들인 문자열에는 개행 문자가 포함될 가능성이 있습니다. 이를 삭제하려면 아래와 같이 코드를 추가합니다。
char *newline = strchr(buffer, 'n');
if (newline) {
    *newline = '�';
}
이 처리를 통해 개행 문자를 널 문자로 교체하여 문자열을 깔끔하게 합니다。

4.2 버퍼 클리어 방법

입력이 버퍼 크기를 초과하는 경우, 입력 스트림에 데이터가 남을 가능성이 있습니다. 이를 방지하기 위해 남은 데이터를 읽어버리는 처리를 추가합니다。
while ((getchar()) != 'n' && !feof(stdin));
이 코드는 개행 문자이거나 파일의 끝에 도달할 때까지 입력 스트림을 클리어합니다。

5. fgets를 사용할 때 주의사항

5.1 오류 처리와 예외 처리의 중요성

fgets는 입력이 성공하면 포인터를 반환하고, 실패한 경우에는 NULL을 반환합니다. 오류가 발생했을 때 적절히 처리하는 것이 중요합니다.
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
    // 오류 처리
}

5.2 베스트 프랙티스

fgets를 사용할 때는 항상 버퍼 크기와 오류 처리를 고려하는 것이 중요합니다. 버퍼 오버플로우와 입력 데이터 검증을 수행하여 안전한 프로그램을 작성합시다.

6. fgets를 활용한 실용적인 코드 예시

6.1 입력 검증 및 정규화

사용자 입력을 처리할 때, 입력 검증과 정규화는 필수입니다. 아래 코드 예시에서는 숫자만 허용하도록 입력을 검증합니다.
char input[10];
if (fgets(input, sizeof(input), stdin) != NULL) {
    // 개행 문자 삭제
    char *newline = strchr(input, 'n');
    if (newline) {
        *newline = '�';
    }

    // 숫자만 허용
    if (strspn(input, "0123456789") == strlen(input)) {
        printf("입력된 숫자:%sn", input);
    } else {
        printf("잘못된 입력입니다. 숫자만 입력해주세요。n");
    }
}

7. 요약

fgets 함수는 C 언어에서 문자열을 안전하게 읽어오기 위한 편리한 도구입니다. gets 함수와 비교했을 때 안전하며, 버퍼 오버플로우 위험을 감소시킵니다. 하지만 fgets를 사용할 때는 개행 문자 처리와 버퍼 정리 등의 고민이 필요합니다. 이 기사에서 소개한 기술을 활용하여, 안전하고 효율적인 입력 처리를 수행합시다.