• 4.6.1 C 스타일 문자열
  • 4.6.2 string library header
  • 4.6.3 string 자료형 사용 시 유의사항

4.6.1 C 스타일 문자열

 

이미 C 언어를 학습한 사람이라면 C 스타일의 문자열을 다룬 기억이 있을 것이다. C 스타일 문자열은 char 자료형을 배열로 지니는 형태이며, 문자열이 담길 경우 마지막에 널 문자('\0')가 들어간다.

#include <iostream>

int main()
{
	using namespace std;

	// 커서를 가져다 올리면 13 길이 배열이라고 표시됨.
	cout << "Hello, World" << endl;
	const char my_strs[] = "Hello, World";

	return 0;
}

문자열의 길이를 확인해보면 12가 아닌 13이라는 것을 알 수 있다.

보이는 길이보다 1 길다.


4.6.2 string library header

 

C++에서는 string 라이브러리를 활용하여 문자열을 다룬다. string은 프로그래머의 편의를 위해 만들어진 사용자 정의 자료형으로 볼 수 있다.

#include <iostream>
#include <string>

int main()
{
	using namespace std;

	const string my_hello = "Hello, World";
	//const string my_hello("Hello, World");
	//const string my_hello{ "Hello, World" };

	cout << my_hello << endl;

	return 0;
}

입력받는 방법은 위에 나열된 3가지 모두 가능하다.

 

숫자를 문자열로 취급하여 받을 수도 있는데, string은 정수를 암시적으로 형 변환을 해주진 않는다. 위에서 언급하였듯이 너무 친숙하여 기본 자료형처럼 보이지만 사용자 정의 자료형이기 때문에 암시적 형 변환이 불가능하다.

#include <string>

int main()
{
	using namespace std;

	// ""를 삭제하고 넣으면 에러가 뜬다.
	const string my_ID = "123";

	return 0;
}

 

또한 string 자료형은 + 연산자에 대한 오버로딩이 구현되어 있어서 문자열을 이어주는 것도 쉽게 수행할 수 있다. 이처럼 문자열을 붙여주는 것을 append라고 하며, 프로그래밍을 공부하다 보면 자주 만나게 될 용어이다. string으로 표현하는 문자열과 C 스타일 문자열의 가장 큰 차이점은 바로 문자열의 길이이다. string 문자열은 널 문자를 가지고 있지 않기 때문에 같은 문자열이라도 길이가 C 스타일 문자열보다 1 짧게 된다.

#include <iostream>
#include <string>

int main()
{
	using namespace std;

	string a("Hello, ");
	string b("World");

	string hw = a + b; // append

	// 12 길이(C 스타일과 길이가 1 차이남.)
	cout << hw.length() << endl;

	hw += " I'm good";
	cout << hw << endl;


	return 0;
}

4.6.3 string 자료형 사용 시 유의사항

 

string을 입력 받을 때는 생각했던 대로 작동하지 않는 경우가 종종 있다. 다음의 예시들을 보자. 아래 예시에서 name 부분에 입력할 문자열을 띄어쓰기가 포함된 문자열을 입력해보자.

#include <iostream>
#include <string>

int main()
{
	using namespace std;

	cout << "Your name ? : ";
	string name;
	cin >> name; // 빈칸이 있으면 이미 다받은 것으로 판단.

	cout << "Your age ? : ";
	string age;
	cin >> age;

	cout << name << " " << age << endl;

	return 0;
}

출력도 해주지 않고 끝나버린다.

문자열을 입력할 때 cin은 띄어쓰기를 만나는 순간 입력이 끝난 줄 알고 저장해준 뒤 다음으로 넘어간다. 이를 해결하는 방법은 여러 가지가 있는데, 그중 하나는 바로 getline을 활용하는 것이다.

 

getline은 enter를 치기 전까지 전부 입력을 받아준다. 이를 이용하면 문자열에 띄어쓰기가 있는 것까지 온전히 받아낼 수 있다.

#include <iostream>
#include <string>

int main()
{
	using namespace std;

	cout << "Your name ? : ";
	string name;
	getline(cin, name);

	cout << "Your age ? : ";
	string age;
	getline(cin, age);

	cout << name << " " << age << endl;

	return 0;
}

 

정수를 먼저 받으면 생기는 오작동도 있다. 이번에는 나이를 먼저 받게 구현을 하면 나이를 입력하자마자 바로 프로그램이 종료되는 것을 볼 수가 있다. int 자료형에 저장하는 경우엔 getline을 사용할 수 없게 되면서 cin으로 사용할 수밖에 없게 되고 숫자를 입력 후 enter를 치는 행위가 getline을 통과하는 조건으로 수행되면서 이러한 문제가 생긴다.

#include <iostream>
#include <string>
#include <limits>

int main()
{
	using namespace std;

	cout << "Your age ? : ";
	int age;
	cin >> age;
	
	// 해결법
	//cin.ignore(32767, '\n'); // 2 byte 가장 큰 signed 정수 32767
	//cin.ignore(numeric_limits<streamsize>::max(), '\n');

	cout << "Your name ? : ";
	string name;
	getline(cin, name); // enter칠때까지 입력 받을 수 있음.

	cout << name << " " << age << endl;

	return 0;
}

이를 해결하기 위해 ignore라는 함수를 활용할 수 있다. ignore 함수의 첫 번째 인자가 입력 받는 길이가 되며, 두 번째 인자가 입력받으면 끝낼 문자가 되겠다. 입력받는 수가 얼마나 길지 모르기 때문에 2byte 가장 큰 signed 정수인 32767을 넣어주었다. 32767이라는 남들이 보기에 이해 못 할 수 있는 숫자를 넣는 것은 다른 사람들을 힘들게 하기 때문에 limit 라이브러리에 있는 streamsize max를 이용해도 되겠다.

+ Recent posts