수성컴전자방입니다. C언어를 공부하시다 보면 문자열을 char형 배열로 표현한다는 것을 아실 수 있습니다. char형 변수는 1 Byte이고 주로 문자를 저장하는 데 사용되므로 char형 배열로 문자열을 표현하는 것이죠. 그러나 Java, python 등 다른 언어들은 문자열을 string으로 표현합니다(특히 객체지향 프로그래밍 언어에서). 그러면 C언어의 특징을 가진 객체지향 프로그래밍 언어인 C++에서는 어떻게 표현할까요? C++에서는 char형 배열과 string 모두 사용이 가능합니다. 오늘은 char[]과 string의 차이점과 변환 방법을 알아보겠습니다.
목차
1. char[] 또는 char*
2. string
3. cin, cout은 char*과 string 둘 다 가능!
4. char*→string 변환 방법
5. string→char* 변환 방법
6. 글 마무리
7. 참고 자료
1. char[] 또는 char*
일단 char[]는 char형 배열이고, char*는 char형 포인터입니다. 그리고 배열의 이름은 그 배열의 주소를 의미하죠. 그래서 소제목에 char[] 또는 char*라고 적었습니다. 3번 문단부터는 char*이라고만 쓰겠습니다.
#include <iostream>
using namespace std;
int main(void)
{
char str1[15]="Hello, world!\n";
for(int i=0; i<15; i++){
cout << "str1[" << i << "]=" << str1[i] << endl;
}
cout << '\n';
cout << str1 << endl;
return 0;
}
Line 6를 보시면 길이가 15인 char형 배열 str1을 선언하고 “Hello, world!\n”를 대입한 것을 보실 수 있습니다. Line 8~10의 for문에 의해 배열의 원소마다 출력됩니다. 그리고 Line 13에서 str1 배열을 한 번에 cout으로 출력합니다. 빌드해서 실행해 보면 아래와 같이 나옵니다.
str1[6]은 아무것도 없는 것 같지만 공백(띄어쓰기)이 있는 것입니다. str1[13]은 개행문자 ‘\n’입니다. str1[14]는 아무것도 없는 것 같지만 NULL이 있는 것입니다. C언어와 C++에서 문자열의 끝은 NULL입니다. 참고로 NULL==’\0’==0입니다. 마지막에 cout << str1 << endl;
도 잘 실행되었습니다.
cstring 라이브러리를 include 하면 strlen(), strcpy(), strcat(), strcmp() 등의 함수를 사용할 수 있습니다.
- size_t strlen(const char* s): 문자열의 길이를 알려주는 함수(단, ‘\0’은 포함하지 않음.)
- char* strcpy(char* dest, const char* src): 문자열을 복사하는 함수(src를 dest에 복사)
- char* strncpy(char* dest, const char* src, size_t n): 문자열을 n Bytes만큼 복사
- char* strcat(char* dest, const char* src): 문자열을 결합하는 함수(dest 뒤에 src를 붙임.)
- char* strncat(char* dest, const char* src, size_t n): 문자열을 결합하는 함수(dest 뒤에 src를 n Bytes만큼 붙임.)
- int strcmp(const char* s1, const char* s2): 문자열을 비교하는 함수(아스키코드 순서로 비교)
- s1>s2: 양수 반환
- s1==s2: 0 반환
- s1<s2: 음수 반환
- 단, s2의 앞부분이 s1이고, s2가 s1보다 더 길 경우 s1<s2로 간주
- int strncmp(const char* s1, const char* s2, size_t n): 문자열을 n자리까지만 비교하는 함수(비교 결과는 strcmp와 같은 방식)
몇 가지만 예를 들어 보겠습니다.
#include <iostream>
#include <cstring>
using namespace std;
int main(void)
{
char str1[100]="Hello, world!\n";
char* str2=new char[20];
strcpy(str2, str1);
for(int i=0; i<15; i++){
cout << "str2[" << i << "]=" << str2[i] << endl;
}
cout << "str2 is " << str2 << endl << endl;
str2[0]='B';
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
cout << "compare: " << strcmp(str1, str2) << endl;
strcat(str1, str2);
cout << "str1: " << str1 << endl;
delete[] str2;
return 0;
}
Line 2에서 cstring을 include합니다.
[Line 8~9]
Line 8에서 길이가 100인 char형 배열 str1을 선언하고 “Hello, world!\n”를 대입했습니다.
Line 7에서 char*형 변수 str2를 선언하고 20 Byte를 동적 할당(Dynamic Allocation)했습니다.
[Line 11~15]
Line 11에서 str1을 str2에 복사했습니다.
Line 12~14의 for문에 의해 str2가 배열의 원소마다 출력됩니다.
Line 15에서 str2 배열을 한 번에 cout으로 출력합니다.
[Line 17~20]
Line 17에서 str2[0]에 ‘B’를 대입합니다.
Line 18~19에서 각 문자열을 출력합니다.
Line 20에서 strcmp(str1, str2)의 결괏값을 출력합니다.
[Line 22~23]
Line 22에서 str1의 뒤에 str2를 붙였습니다.
Line 23에서 str1을 출력합니다.
실행 결과는 아래와 같습니다.
위의 스크린샷에서 마지막 두 줄은 str1이 “Hello, world!\nBello, world!”이고, 중간의 ‘\n’이 개행문자라서 두 줄에 결쳐 출력된 것입니다.
2. string
string은 변수처럼 사용할 수 있지만 엄밀히 말하면 객체입니다. 그러나 편의상 ‘변수’라고 칭하겠습니다. string 변수를 사용하려면 먼저 string 라이브러리를 include 해야 합니다.(cstring 아님!!)
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string str1="Hello,";
string str2="world!";
string strt=str1+str2;
cout << str1 << endl;
cout << str2 << endl;
cout << strt << endl << endl;
cout << "the length of str1: " << str1.length() << endl;
cout << "the length of str2: " << str2.length() << endl;
if(str1>str2){
cout << "str1>str2" << endl;
}
else if(str1<str2){
cout << "str1<str2" << endl;
}
else{
cout << "str1==str2" << endl;
}
return 0;
}
위의 예제 코드로 살펴보겠습니다.
Line 2에서 string을 include합니다.
[Line 8~10]
Line 8~9에서 string 변수 str1과 str2를 생성하고 각각 내용을 입력하였습니다.
Line 10에서는 string 변수 strt를 생성하고 str1+str2를 대입했습니다. 이렇게 하면 간단하게 str1과 str2를 이어 붙일 수 있습니다.(결과: strt=”Hello,world!”)
[Line 16~17]
문자열의 길이를 보려면 객체명.length()를 사용합니다.
[Line 19~27]
str1과 str2를 아스키코드 기준으로 비교하는 코드입니다. string을 사용할 때에는 함수를 따로 사용하지 않아도 >, <, ==으로 쉽게 비교할 수 있습니다.
빌드 및 실행 결과는 아래와 같습니다.
예제에서 빠뜨린 내용이 있는데, char*형처럼 str1[0], str1[1], … 등의 방식으로도 접근 가능합니다.
3. cin, cout은 char*과 string 둘 다 가능!
cin, cout은 사실 char*, string뿐 아니라 int, double 등 거의 모든 자료형에 바로 사용할 수 있는 것 아시죠? 심지어 직접 만든 class도 Operator Overloading 후 cin, cout을 사용할 수 있습니다.
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
char str1[10]={0};
string str2; //string str2=0;으로 하면 안 됨.
cout << "Enter str1" << endl;
cin >> str1;
cout << "Enter str2" << endl;
cin >> str2;
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
return 0;
}
예제 코드입니다. 이건 굳이 실행 결과를 안 보여드려도 될 것 같아요.
4. char*→string 변환 방법
cin, cout이 char*와 string 모두 지원하긴 하지만, 그래도 여러 가지 함수를 사용하다 보면 char*과 string 간의 변환이 필요할 때가 있습니다. 먼저 char*→string 변환 방법부터 알아보겠습니다. 사실 char*→string 변환은 쉽습니다. 그냥 string 변수에 char*형 변수를 대입하면 됩니다. char형 배열이라면 배열의 이름을 대입하면 되겠죠?
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
char str_char[15]="Hello, world!\n";
string str_string=str_char; //여기 보세요!
cout << str_string << endl;
return 0;
}
Line 9이 핵심입니다.
string str_string=str_char;
string 변수에 char형 배열의 이름을 대입하니 string 변수에 잘 저장됩니다.
빌드 및 실행 결과입니다.
5. string→char* 변환 방법
string→char*의 경우 반대와 다르게 한 가지 과정이 더 추가됩니다. 사실 과정이라 할 것도 없습니다. string 변수 뒤에 .c_str()를 붙여 주면 char형 배열이 됩니다.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main(void)
{
string str_string="Convert test!\n";
char str_char[20]={0};
strcpy(str_char, str_string.c_str()); //여기 보세요!
cout << str_char << endl;
return 0;
}
Line 12가 핵심입니다.
strcpy(str_char, str_string.c_str());
string 뒤에 .c_str를 붙이니 char*로 변환되어서 strcpy 함수를 사용할 수 있게 되었습니다.
위의 예제 코드를 빌드하고 실행한 결과입니다.
6. 글 마무리
제 글을 읽어 주셔서 감사합니다. 다음에 만나요!
7. 참고 자료
1) matters_. 2019. “[C++] 문법 char to string , string to char 변환”, What matters the most to you, Why. (2023. 01. 11. 방문). https://shjz.tistory.com/91
2) 달승. 2021. “C++ ] 문자열(string, char)”, 달려라 승이. (2023. 01. 01. 방문). https://dkanxmstmdgml.tistory.com/396
3) 에르주. 2020. “[C++] char*, char[], string 변수의 차이”, 주에르 블로그. (2023. 01. 11. 방문). https://erjuer.tistory.com/57