c++ int를 문자배열로 만들기
────────────────────────────
목차
- int와 문자, 문자열 간 변환
1-1. int ↔ char 간 변환
1-2. int ↔ string 간 변환
1-3. C 스타일 문자열 변환 - static_cast vs reinterpret_cast
- C++ string 관련 함수 정리
- string → 문자 배열 (char[]) 변환
- 주의 사항 및 요약 비교
- 직접 char 배열로 변환하는 방법
────────────────────────────
1. int와 문자, 문자열 간 변환
1-1. int ↔ char 간 변환
① int → char 변환
정수형 값을 문자로 변환하는 방법은 정수 값에 문자 '0'(또는 아스키 코드 48)을 더하는 방식입니다.
예시 코드:
int before = 3;
char after = before + '0'; // 또는 before + 48
// '0'의 아스키 코드는 48이므로, 3 + 48 = 51이며, 이는 문자 '3'에 해당함.
② char → int 변환
문자형 값을 정수형 값으로 변환할 때는 해당 문자에서 '0'(또는 48)을 빼면 됩니다.
예시 코드:
char before = '3';
int after = before - '0'; // 또는 before - 48
// '3'의 아스키 코드 51에서 48을 빼면 정수 3이 됨.
────────────────────────────
1-2. int ↔ string 간 변환
① int → string 변환
C++ 표준 라이브러리의 std::to_string 함수를 사용하면, int형 변수를 문자열로 손쉽게 변환할 수 있습니다.
int before = 100;
std::string s = std::to_string(before);
② string → int 변환
문자열을 정수로 변환할 때에는 std::stoi 함수를 사용합니다.
std::string s = "100";
int i = std::stoi(s);
참고로, 숫자와 문자가 혼합된 문자열, 예를 들어 "1 to 100"과 같은 경우 std::stoi는 맨 앞의 숫자만을 변환하여 정수 1을 반환함을 유념하여야 합니다.
────────────────────────────
1-3. C 스타일 문자열 변환
① int → char 변환*
정수형을 문자 배열(문자열)로 변환하는 데에는 몇 가지 방법이 있으며, 그 중 대표적인 것은 sprintf 함수를 사용하는 것입니다.
- sprintf 사용 예제:
#include <stdio.h>
int num = 500;
char buffer[10];
sprintf(buffer, "%d", num);
참고: 버퍼 크기를 초과하는 경우를 방지하기 위해 snprintf 사용을 권장드립니다.
또한, MS 전용 비표준 함수인 itoa를 사용할 수도 있습니다.
- itoa 사용 예제:
#include <stdlib.h>
int num = 100;
char buffer[10] = {0,};
itoa(num, buffer, 10); // 10진수 기준 변환
주의: 리눅스나 macOS 환경에서는 지원되지 않을 수 있으므로, 상황에 맞게 sprintf 혹은 snprintf를 활용하는 것이 바람직합니다.
② string → char 변환*
문자열 객체에서 C 스타일의 문자열(문자 배열)로 변환할 때는 c_str() 함수를 사용합니다.
- 예시 코드:
#include <string>
std::string str = "Hello";
const char* arr = str.c_str();
주의: c_str()가 반환하는 포인터는 const char* 타입이므로, 수정이 불가합니다.
────────────────────────────
2. static_cast vs reinterpret_cast
두 캐스트 연산자는 용도와 안전성에서 차이가 있습니다.
구분 | static_cast | reinterpret_cast |
목적 | 논리적 변환, 타입 간 변환(자료형 변환) | 메모리 재해석, 포인터 타입 변환 등 |
사용 예시 | int → float, base → derived 변환, void* → 특정 타입 포인터 변환 등 | 포인터 간 변환, 정수 ↔ 포인터 변환 등 |
안전성 | 컴파일러의 검사를 통하여 비교적 안전함 | 메모리 레벨의 해석으로 인하여 위험할 수 있음 |
예시 코드:
int i = 10;
float f = static_cast<float>(i); // OK: int를 float로 변환
void* vp = &i;
// int* ip = static_cast<int*>(vp); // 오류: void*를 static_cast로 변환하는 것은 불가능함
int* ip2 = reinterpret_cast<int*>(vp); // OK, 단 주의 필요!
────────────────────────────
3. C++ string 관련 함수 정리
다음은 C++의 std::string 클래스에서 자주 사용되는 함수들에 관한 정리입니다.
함수 | 설명 | 예시 |
length() / size() | 문자열의 길이를 반환 | s.length() |
substr(pos, len) | 지정한 위치에서부터 len 길이만큼 부분 문자열 추출 | s.substr(0, 5) |
find(str) / find(c) | 특정 문자열 또는 문자를 찾음 | s.find("apple") |
replace(pos, len, str) | 지정한 부분 문자열을 다른 문자열로 치환 | s.replace(0, 3, "Hi") |
append(str) / += | 문자열을 덧붙임 | s += "!" |
compare(str) | 두 문자열의 동일 여부 비교 (동일하면 0 반환) | s.compare("test") == 0 |
c_str() | C 스타일 문자열(널 종료된 문자열) 반환 | printf("%s", s.c_str()); |
empty() | 문자열이 비었는지 확인 | if (s.empty()) |
erase(pos, len) | 문자열의 일부를 제거 | s.erase(0, 2) |
insert(pos, str) | 특정 위치에 문자열을 삽입 | s.insert(0, ">>") |
stoi, stof, stod | 문자열을 각각 int, float, double형으로 변환 | int n = std::stoi(s); |
to_string() | 숫자를 문자열로 변환 | std::to_string(42); |
Tip: 실무에서는 특히 substr, find, replace, stoi, to_string, c_str()의 사용 빈도가 높습니다.
────────────────────────────
4. string → 문자 배열 (char[]) 변환
문자열(std::string)을 char 배열로 변환하는 방법에는 여러 가지가 있습니다.
① string::copy() 사용
- 설명: 문자열 복사 시 널 종료 문자('\0')는 자동으로 복사되지 않으므로, 복사 후에 수동으로 추가할 필요가 있습니다.
- 예시 코드:
#include <string>
std::string s = "Hello";
char chars[s.length() + 1]; // 널 종료 문자를 위한 공간 확보
s.copy(chars, s.length());
chars[s.length()] = '\0'; // 수동으로 null 종료 문자 추가
② strcpy() 사용 (C 스타일)
- 설명: C 스타일 문자열 복사는 자동으로 널 종료 문자를 포함하지만, 버퍼 오버플로우 위험이 있으므로 버퍼 크기를 주의해야 합니다.
- 예시 코드:
#include <string>
#include <cstring>
std::string s = "Hello";
char chars[s.length() + 1];
strcpy(chars, s.c_str());
③ strncpy() 사용 (더 안전한 복사)
- 설명: 버퍼 크기를 제한하여 안전하게 복사할 수 있으나, 널 종료 문자는 수동으로 지정해 주어야 합니다.
- 예시 코드:
#include <string>
#include <cstring>
std::string s = "Hello";
char chars[s.length() + 1];
strncpy(chars, s.c_str(), sizeof(chars));
chars[sizeof(chars) - 1] = '\0'; // 수동으로 null 종료 문자 지정
④ c_str() 직접 사용
- 설명: 읽기 전용 C 스타일 문자열이 필요할 경우 사용합니다.
- 예시 코드:
#include <string>
std::string s = "Hello";
const char* chars = s.c_str();
⑤ &s[0] 사용
- 설명: C++11 이후에는 문자열 내부 버퍼에 직접 접근하여 수정 가능한 char 배열 포인터로 활용할 수 있습니다.
- 예시 코드:
#include <string>
std::string s = "Hello";
char* chars = &s[0]; // 수정 가능한 배열 포인터로 사용 가능
주의 사항:
- c_str() 함수가 반환하는 포인터는 const char* 타입임으로, 수정하는 것은 올바르지 않습니다.
- &s[0] 방식은 문자열이 비어 있지 않은 경우에만 안전하며, 내부 버퍼를 직접 수정할 경우 null 종료 문자를 직접 관리하여야 합니다.
────────────────────────────
5. 주의 사항 및 요약 비교
각 변환 방법은 용도와 상황에 따라 적절하게 선택하여 사용하여야 합니다. 일반적인 문자열 변환에서는 C++ 표준 라이브러리의 std::to_string, std::stoi 등의 함수를 사용하는 것이 안전하며 간편합니다. 반면, char 배열에 직접 접근해야 하거나 성능, 메모리 관리의 제어가 필요한 상황에서는 sprintf, snprintf, strcpy, strncpy 등의 C 스타일 함수를 신중하게 사용하여야 합니다. 또한, 캐스팅 시에는 static_cast와 reinterpret_cast의 차이를 명확히 이해하여 안전하게 사용하도록 주의 바랍니다.
────────────────────────────
6. 직접 char 배열로 변환하는 방법
char 배열로 직접 변환하는 방법은 앞서 설명드린 두 가지 방법을 상황에 따라 선택하여 사용하시면 됩니다.
- std::snprintf 사용:
숫자의 자릿수를 동적으로 계산한 후, 적절한 크기의 배열을 할당하여 사용합니다.
예시 코드: - #include <iostream> #include <cmath> #include <cstdio> int main() { int number = 12345; int digits = number == 0 ? 1 : static_cast<int>(std::log10(std::abs(number))) + 1; if (number < 0) digits++; // 음수인 경우 부호를 위한 공간 추가 char* charArray = new char[digits + 1]; // '\0' 문자 포함 공간 확보 std::snprintf(charArray, digits + 1, "%d", number); std::cout << charArray << std::endl; delete[] charArray; return 0; }
- std::string과 결합하여 사용:
std::string으로 변환 후, char 배열로 복사하는 방법입니다.
예시 코드: - #include <iostream> #include <string> #include <cstring> int main() { int number = 12345; std::string str = std::to_string(number); char* charArray = new char[str.length() + 1]; std::strcpy(charArray, str.c_str()); std::cout << charArray << std::endl; delete[] charArray; return 0; }
────────────────────────────
결론
C++에서의 자료형 변환 및 문자열 처리에서는 상황에 따른 적절한 도구와 함수의 선택이 중요합니다.
- 일반적인 변환 작업에는 C++ 표준 함수(std::to_string, std::stoi, c_str() 등)를 활용하는 것이 코드의 간결함과 안정성을 보장합니다.
- 고성능이 요구되거나 메모리 관리가 필요한 경우, C 스타일의 함수와 직접 char 배열을 사용하는 방법을 고려할 수 있습니다.
- 캐스트 연산자 사용 시, static_cast와 reinterpret_cast의 차이를 명확히 이해함으로써 잘못된 메모리 접근이나 예기치 않은 동작을 방지할 수 있음을 유념하여 주시기 바랍니다.
────────────────────────────
참고 자료