string 헤더에 포함되어 있는 기존의 strcat() 함수는 인자를 2개만 받는다는 단점이 있다.
C++ 에서 사용하는 std::string을 이용하다가 char[] 형태의 문자열을 다루게 되면 3개 이상의 char[] 문자열을 한 번에 합친 결과를 얻고 싶을 때가 종종 있다. 따라서 이번에 가변 인자를 활용하는 김에 3개 이상의 문자열을 합치는 strcat() 함수를 만들어보기로 했다.
가변 인자에 관한 설명은 [여기]에 상세히 되어있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <iostream> using std::cout; using std::endl; #include <string> // strcat #include <cstdarg> // 가변 인자 헤더 #include <algorithm> // std::fill char * strCatAll(char * str1, char * str2, ...) { char * result = new char[65536]; std::fill(result, result + 65536, '\0'); va_list argList; // 가변 인자 선언 va_start(argList, str2); // 가변 인자 초기화 strcat(result, str1); strcat(result, str2); char * str = nullptr; while (true) { char * str = va_arg(argList, char *); // 인자 가져옴 if (str != nullptr) { strcat(result, str); } else { break; } // nullptr을 만나면 종료 } va_end(argList); // 가변 인자 사용 완료 return result; } int main(void) { cout << strCatAll("hello", "world", nullptr) << endl; cout << strCatAll("hello", "world", " by ", nullptr) << endl; cout << strCatAll("hello", "world", " by ", "TAE IN", nullptr) << endl; return 0; } |
주석까지 참고하면 코드를 이해할 수 있을 것이다. 완전 C로 코딩해야 한다면 std::fill 대신 memset을 이용해도 좋다. 주의할 점은 함수를 호출할 때 예제처럼 마지막 인자는 nullptr을 넣어줘야 제대로 처리를 할 수 있다는 것이다. 개인적으로 쓴다면 상관없지만 공공에 배포하는 프로그램이라면 이 부분에 예외 처리나 Assert 처리를 해줘야 할 것이다.
특히 참고해야 할 점은 va_start의 두 번째 인자는 처음 va_arg를 호출할 때 가져올 인자를 결정한다는 것이다. 만약 str1을 넣었다면 va_arg를 처음 호출할 때 str2가 반환될 것이고, 예제처럼 str2를 넣으면 3번째 인자가 반환될 것이다.