본문 바로가기

개발 공부/C++

따라하며 배우는 C++ 17. string 문자열 클래스

따라하며 배우는 C++ 17. string 문자열 클래스

 

17.1 std::string과 std::wstring

 

#include <string>
#include <cstddef>
#include <iostream>
#include <locale>
using namespace std;

int main()
{
	// c-style string example
	//{
	//	char* strHello = new char[7];
	//	strcpy_s(strHello, sizeof(char) * 7, "hello!");
	//	std::cout << strHello << std::endl;
	//}

	// basic_string<>, string, wstring
	{
		std::string string;
		std::wstring wstring;

		wchar_t wc; //wide character 혹은 unicode를 표현할 때
	}
	return 0;
}

 

 

외국어를 표현하는 예제

 

 

17.2 std::string의 여러가지 생성자들과 형변환

 

#include <string>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
	std::string my_string("my string");
	std::cout << my_string << std::endl;

	std::string second_string(my_string);
	std::cout << second_string << std::endl;

	std::string third_string(my_string, 3);
	std::cout << third_string << std::endl;
	
	std::string fourth_string(my_string, 3, 2);
	std::cout << fourth_string << std::endl;

	const char* fifth_string = "my stirng";
	std::string sixth_string(fifth_string);
	std::cout << fifth_string << std::endl;
	std::cout << sixth_string << std::endl;

	std::string seventh_string(10, 'A');
	std::cout << seventh_string << std::endl;

	std::vector<char> vec;
	for (auto e : "Today is a good day.")
		vec.push_back(e);

	std::string eight_string(vec.begin(), vec.end());

	std::cout << eight_string << std::endl;

	std::string nineth_string(vec.begin(), std::find(vec.begin(), vec.end(), 'y'));
	std::cout << nineth_string << std::endl;
	return 0;
}

 

#include <string>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
	//불가능 std::string my_str(4);
	std::string my_str(std::to_string(1004));
	std::cout << my_str << std::endl;
	my_str += std::to_string(128);
	std::cout << my_str << std::endl;

	int i = std::stoi(my_str);
	std::cout << i << std::endl;

	float f = std::stof(my_str);
	std::cout << f << std::endl;
	return 0;
}

#include <string>
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
template <typename T>
std::string ToString(T x)
{
	std::ostringstream osstream;
	osstream << x;
	return osstream.str();
	//이 함수는 stream으로 들어온 것을 무엇이 됐건 string으로 바꿔 return
}
int main()
{
	//불가능 std::string my_str(4);
	std::string my_str(ToString(3.14245));
	std::cout << my_str << endl;
	return 0;
}

 

 

#include <string>
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
template <typename T>
std::string ToString(T x)
{
	std::ostringstream osstream;
	osstream << x;
	return osstream.str();
	//이 함수는 stream으로 들어온 것을 무엇이 됐건 string으로 바꿔 return
}

//String으로 들어온 것을 T 변수형으로 변환할 수 있는지를 return 함.
template <typename T>
bool FromString(const std::string& str, T& x)
{
	std::istringstream isstream(str);
	//스트림을 초기화할 때 string을 넣어 초기화함.
	return (isstream >> x) ? true : false;
}
int main()
{
	//불가능 std::string my_str(4);
	std::string my_str(ToString(3.14245));
	double d;
	if (FromString(my_str, d))
		std:cout << d << std::endl;
	else
		std::cout << "Cannot convent" << std::endl;
	std::cout << my_str << endl;
	return 0;
}

 

 

 

17.3 std::string의 길이와 용량

 

#include <string>
#include <iostream>
using namespace std;


int main()
{
	string my_str("012345678");
	cout << my_str.size() << endl;
	cout << my_str.length() << endl;
	cout << my_str.capacity() << endl;
	cout << my_str.max_size() << endl;
	//c-style에서는 '\0'이 숨어 있었지만
	//string에서는 쓸데없는 문자를 셀 필요가 없다.
	//내부적으로 문자열의 길이를 갖고 있기 때문에,

	//string도 vector처럼 가급적 reallocation을 안하려고 든다.

	cout << std::boolalpha;
	cout << my_str.empty() << endl;

	string my_str2("");
	cout << my_str2.empty() << endl;

}

 

vector처럼 reserve(1000);로 메모리를 미리 할당받을 수 있다.

 

 

17.4 문자 접근하기와 배열로의 변환

 

#include <string>
#include <iostream>
#include <vector>
using namespace std;


int main()
{
	string my_str("abcdefg");
	cout << my_str << endl;

	cout << my_str[0] << endl;
	cout << my_str[3] << endl;

	my_str[3] = 'z';
	cout << my_str << endl;

	//my_str[100] = 'X'; //runtime error
	//심지어 위와 같이 쓰면 exceoption 발생도 되지 않음.
	//아래와 같이 쓰면 가능.
	/*try {
		my_str,at(100) = 'X';
	}
	catch (std::exception& e)
	{ //Invalid string position
		cout << e.what() << endl;
	}
	return 0;*/

}

 

 

 

vector에서도 마찬가지이다.

my_str[100] 이런 형식은 퍼포먼스가 더 중요할 떄,

my_str.at(100) 형식은 안정성이 더 중요할 때 많이 쓰인다.

 

#include <string>
#include <iostream>
#include <vector>
using namespace std;


int main()
{
	string my_str("abcdefg");
	cout << my_str.c_str() << endl; //c-style 문자열로 변경
	const char* arr = my_str.c_str();
	cout << (int)arr[6] << endl;
	cout << (int)arr[7] << endl; //0 출력
	//string 자체에는 null 캐릭터가 저장되지 않지만
	//C-style로 가져오면 null 캐릭터를 넣어준다.

	//my_str.data() 도 거의 c_str처럼 쓰일 수 있다.
	return 0;

}
#include <string>
#include <iostream>
#include <vector>
using namespace std;


int main()
{
	string my_str("abcdefg");
	char buf[20];
	my_str.copy(buf, 5, 0);
	cout << buf << endl;

	buf[5] = '\0';
	cout << buf << endl;
	return 0;

}

= 에서는 자체적으로 null을 넣어주진 않는다.

 

 

 

17.5 string 대입, 교환, 덧붙이기, 삽입.

 

#include <string>
#include <iostream>
#include <vector>
using namespace std;


int main()
{
	string str1("one");
	cout << str1 << endl;

	string str2;
	str2 = str1;
	str2 = "two";
	str2.assign("two");

	cout << str2 << endl;
	str2.assign("string2").append(" ").append("three"); //chaining 구조

	cout << str2 << endl;

	string str3("A");
	string str4("B");
	cout << str3 << " " << str4 << endl;
	std::swap(str1, str2);
	cout << str3 << " " << str4 << endl;
	str1.swap(str2);
	cout << str3 << " " << str4 << endl;

	string str5("five");
	str5.push_back('A'); //글자 하나씩만 가능.

	string str("aaaa");
	str.insert(2, "bbb");
	cout << str << endl;
	return 0;

}