Core Programming/C Standard Library: Resource & Performan

C언어 문자열 숫자 변환: atoi, atof 대신 strtol을 써야 하는 이유 (정리)

임베디드 친구 2025. 2. 15. 11:34
반응형

C언어 문자열 숫자 변환 가이드: atoi, atof 그리고 더 안전한 방법

C언어 프로그래밍 중 사용자 입력이나 파일로부터 읽어온 문자열을 숫자(정수, 실수)로 변환해야 하는 경우가 많습니다. 가장 흔히 사용되는 atoi와 atof 함수의 사용법과 함께, 실무에서 발생할 수 있는 치명적인 오류를 방지하는 대안까지 정리해 드립니다.

Generated by Gemini AI.


1. 한눈에 보는 요약 (Quick Summary)

함수 헤더 변환 타입 특징
atoi stdlib.h int 문자열 → 정수. 간단하지만 오류 감지 불가
atof stdlib.h double 문자열 → 실수. 지수 표현(e) 지원
strtol stdlib.h long 권장. 변환 실패 및 남은 문자 확인 가능

2. atoi 함수 (ASCII to Integer)

atoi는 문자열의 앞부분에서 숫자로 변환 가능한 부분을 찾아 int형 정수로 반환합니다.

함수 원형

C
 
#include <stdlib.h> // 주의: string.h가 아닌 stdlib.h입니다.
int atoi(const char *str);

동작 특징

  • 공백은 자동으로 무시됩니다.
  • +, - 부호를 인식합니다.
  • 숫자가 아닌 문자를 만나면 그 전까지의 결과만 반환합니다.
  • 중요: 변환이 불가능할 경우 0을 반환하므로, 실제 값 0과 변환 실패를 구분할 수 없습니다.

예제 코드

C
 
#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("정수 변환: %d\n", atoi("1234"));    // 1234
    printf("공백 포함: %d\n", atoi("  -567")); // -567
    printf("혼합 문자: %d\n", atoi("42abc"));  // 42
    printf("변환 실패: %d\n", atoi("hello"));  // 0 (구분 불가)
    return 0;
}

3. atof 함수 (ASCII to Float)

atof는 문자열을 double 타입의 실수로 변환합니다.

함수 원형

C
 
#include <stdlib.h>
double atof(const char *str);

동작 특징

  • 소수점(.)과 지수 표현식(e 또는 E)을 지원합니다.
  • atoi와 마찬가지로 변환 실패 시 0.0을 반환하며 예외 처리가 어렵습니다.

예제 코드

C
 
#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("실수 변환: %f\n", atof("3.14"));    // 3.140000
    printf("지수 표현: %f\n", atof("2.71e3"));  // 2710.000000
    printf("변환 실패: %f\n", atof("abc"));     // 0.000000
    return 0;
}

4. ⚠️ atoi와 atof의 치명적인 한계

단순한 과제용 코드라면 괜찮지만, 실제 서비스나 임베디드 시스템에서는 아래와 같은 이유로 사용을 지양해야 합니다.

  1. 오류 감지 불가: "0"을 넣었을 때와 "abc"를 넣었을 때 모두 결과값이 0입니다. 데이터 무결성이 중요한 시스템에서 치명적입니다.
  2. 오버플로우 대처 불가: int 범위를 넘어가는 큰 숫자가 입력될 경우 정의되지 않은 동작(Undefined Behavior)이 발생할 수 있습니다.

5. 더 안전한 대안: strtol 및 strtod

구글 검색 상위 노출을 노리는 핵심 해결책입니다. 실무에서는 strtol(String to Long) 계열 함수를 사용하는 것이 표준입니다.

strtol 활용 예제 (오류 검출 포함)

C
 
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
    const char *str = "123abc45";
    char *endptr;
    
    // 10진법으로 변환
    long val = strtol(str, &endptr, 10);

    if (str == endptr) {
        printf("변환 실패: 숫자가 전혀 없습니다.\n");
    } else {
        printf("변환된 숫자: %ld\n", val);
        printf("남은 문자열: %s\n", endptr); // "abc45" 출력
    }

    return 0;
}
  • endptr을 통해 숫자가 어디까지 읽혔는지 알 수 있어 파싱에 매우 유리합니다.
  • errno를 통해 오버플로우 발생 여부도 체크 가능합니다.

결론: 어떤 함수를 써야 할까?

  1. 입력 데이터가 100% 숫자임이 보장될 때: atoi, atof (간결함)
  2. 사용자 입력이나 네트워크 데이터를 다룰 때: 무조건 strtol, strtod 사용 권장

정확한 예외 처리는 견고한 소프트웨어의 기본입니다. 특히 리소스가 제한적인 임베디드 환경에서는 잘못된 데이터 입력이 시스템 다운으로 이어질 수 있으므로 항상 안전한 함수를 선택하시기 바랍니다.


포스팅이 도움이 되셨다면 하트(♥)와 댓글 부탁드립니다!

임베디드 소프트웨어 및 최적화 기법에 대한 전문적인 정보는 'Coding by Head' 블로그에서 계속됩니다.

https://coding-by-head.tistory.com/

반응형