Core Programming/C Standard Library: Resource & Performan

C언어 문자열 숫자 변환 끝판왕: strtol, strtod 완벽 가이드 (에러 처리 포함)

임베디드 친구 2025. 2. 16. 12:08
반응형

C언어 문자열 숫자 변환: strtol, strtod로 안전하고 완벽하게

C언어에서 문자열을 숫자로 바꿀 때 가장 먼저 배우는 atoi, atof는 사용하기 편하지만, 변환 실패를 감지할 수 없다는 치명적인 단점이 있습니다.

오늘은 실무 환경이나 임베디드 시스템에서 데이터 무결성을 보장하기 위해 반드시 사용해야 하는 strtolstrtod 함수를 완벽하게 정리해 보겠습니다.

Generated by Gemini AI.


1. 왜 strtol, strtod 인가? (장점 비교)

많은 개발자가 atoi 대신 이 함수들을 선택하는 이유는 세 가지입니다.

  1. 에러 검출 가능: 숫자가 아닌 문자가 섞였을 때 어디서 멈췄는지(endptr) 알 수 있습니다.
  2. 오버플로우 체크: long 범위를 벗어나는 입력을 errno로 잡아낼 수 있습니다.
  3. 다양한 진법 지원: 10진수뿐만 아니라 2진수, 16진수 등을 자유롭게 변환합니다.

2. 정수 변환의 정석: strtol

strtol은 문자열을 long 타입 정수로 변환하며, 특히 진법(base) 설정이 가능해 하드웨어 제어나 통신 프로토콜 구현 시 유용합니다.

함수 원형

C
 
#include <stdlib.h>
long strtol(const char *nptr, char **endptr, int base);

핵심 매개변수

  • nptr: 변환할 문자열
  • endptr: 숫자가 끝난 지점의 포인터를 저장 (변환되지 않은 나머지 문자열 확인용)
  • base: 진법 (2~36). 0을 입력하면 0x(16진수), 0(8진수) 등을 자동으로 인식합니다.

예제: 진법 변환과 남은 문자열 처리

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

int main() {
    char str[] = "0x1F is 31 in decimal";
    char *endptr;
    
    // 0을 넣어 자동으로 16진수(0x) 인식
    long value = strtol(str, &endptr, 0);

    printf("변환된 값: %ld (10진수)\n", value); // 31
    printf("읽지 못한 부분: %s\n", endptr);     // " is 31 in decimal"
    
    return 0;
}

3. 실수 변환의 정석: strtod

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

함수 원형

C
 
#include <stdlib.h>
double strtod(const char *nptr, char **endptr);

예제: 데이터 파싱 활용

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

int main() {
    char sensor_data[] = "23.57 Celsius";
    char *endptr;
    
    double temp = strtod(sensor_data, &endptr);

    printf("현재 온도: %.2f\n", temp);   // 23.57
    printf("단위: %s\n", endptr);       // " Celsius"
    
    return 0;
}

4. 실무용 에러 처리 템플릿 (Best Practice)

수익형 블로그의 핵심인 '정보의 질'을 높이기 위해, 실무에서 그대로 복사해서 쓸 수 있는 에러 처리 패턴을 제시합니다.

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

void safe_convert(const char *input) {
    char *endptr;
    errno = 0; // 에러 상태 초기화

    long val = strtol(input, &endptr, 10);

    // 1. 오버플로우/언더플로우 체크
    if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) {
        perror("Range Error");
        return;
    }

    // 2. 숫자가 전혀 없는 경우
    if (endptr == input) {
        printf("Error: 변환할 숫자가 없습니다. 입력값: %s\n", input);
        return;
    }

    // 3. 변환 성공 (뒤에 문자가 남았는지 여부도 확인 가능)
    printf("성공: %ld", val);
    if (*endptr != '\0') printf(" (남은 문자: %s)", endptr);
    printf("\n");
}

int main() {
    safe_convert("99999999999999999999"); // 오버플로우 예시
    safe_convert("Hello123");             // 변환 실패 예시
    safe_convert("12345");                // 정상 예시
    return 0;
}

결론: 안전한 코딩의 시작

strtol과 strtod는 단순히 숫자를 바꾸는 도구가 아니라, 프로그램의 예외 상황을 통제할 수 있게 해주는 안전장치입니다.

  • 단순 변환은 atoi, atof를 써도 좋지만,
  • 사용자 입력, 네트워크 패킷, 설정 파일 등을 다룰 때는 반드시 strtol, strtod를 사용하세요!

임베디드 소프트웨어 개발에서 한 줄의 견고한 코드가 시스템 전체의 안정성을 결정합니다.


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

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

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

반응형