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

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의 치명적인 한계
단순한 과제용 코드라면 괜찮지만, 실제 서비스나 임베디드 시스템에서는 아래와 같은 이유로 사용을 지양해야 합니다.
- 오류 감지 불가: "0"을 넣었을 때와 "abc"를 넣었을 때 모두 결과값이 0입니다. 데이터 무결성이 중요한 시스템에서 치명적입니다.
- 오버플로우 대처 불가: 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를 통해 오버플로우 발생 여부도 체크 가능합니다.
결론: 어떤 함수를 써야 할까?
- 입력 데이터가 100% 숫자임이 보장될 때: atoi, atof (간결함)
- 사용자 입력이나 네트워크 데이터를 다룰 때: 무조건 strtol, strtod 사용 권장
정확한 예외 처리는 견고한 소프트웨어의 기본입니다. 특히 리소스가 제한적인 임베디드 환경에서는 잘못된 데이터 입력이 시스템 다운으로 이어질 수 있으므로 항상 안전한 함수를 선택하시기 바랍니다.
포스팅이 도움이 되셨다면 하트(♥)와 댓글 부탁드립니다!
임베디드 소프트웨어 및 최적화 기법에 대한 전문적인 정보는 'Coding by Head' 블로그에서 계속됩니다.
반응형
'Core Programming > C Standard Library: Resource & Performan' 카테고리의 다른 글
| C언어 동적 메모리 할당 총정리: malloc, calloc, realloc, free 완벽 가이드 (0) | 2025.02.17 |
|---|---|
| C언어 문자열 숫자 변환 끝판왕: strtol, strtod 완벽 가이드 (에러 처리 포함) (0) | 2025.02.16 |
| C언어 문자열 검색 완벽 가이드: strspn과 strcspn 차이 및 실전 활용법 (0) | 2025.02.14 |
| C언어 문자열 자르기와 복제: strtok, strdup 완벽 가이드 (메모리 관리 팁) (0) | 2025.02.13 |
| C언어 문자열 검색 완벽 가이드: strchr과 strstr 함수 사용법 및 차이점 (0) | 2025.02.12 |