Search

String Class 까보기

간단소개
42 Cadet dcho 라고 합니다. 개인 노션에 글은 정말 많은데 처음으로 공유 하네요. 반갑습니다!
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
C++
Scrap
태그
9 more properties

String Class 를 까보자

왜 필자가 String Class를 까는지는 각 subtitle의 문제점을 직면했기 때문이다.

1. const char * 을 String객체로 알잘딱 해서 type casting 해준다고?

먼저 String Class를 구현해 보았다.(사실 윤성우 열혈 C++ 에서 가져옴)
// StringClass.cpp #include <iostream> #include <cstring> using namespace std; class String { private: int len; char * str; public: String(); String(const char * s); String(const String& s); ~String(); String& operator= (const String& s); String& operator+= (const String& s); bool operator== (const String& s) const; String operator+ (const String& s); friend ostream& operator<< (ostream& os, const String& s); friend istream& operator>> (istream& os, String& s); }; String::String() :len(0), str(NULL) {} String::String(const char * s) { len = strlen(s) + 1; str = new char[len]; strcpy(str, s); } String::String(const String& s) { len = s.len; str = new char[len]; strcpy(str, s.str); } String::~String() { if (str != NULL) delete[] str; } String& String::operator= (const String& s) { if (str != NULL) delete[] str; len = s.len; str = new char[len]; strcpy(str, s.str); return (*this); } String& String::operator+= (const String& s) { len += (s.len - 1); char* tempStr = new char[len]; strcpy(tempStr, str); strcat(tempStr, s.str); if (str != NULL) delete[] str; str = tempStr; return (*this); } bool String::operator== (const String& s) const { return (strcmp(str, s.str) ? false : true); } String String::operator+ (const String& s) { char* tempStr = new char[len + s.len - 1]; strcpy(tempStr, str); strcat(tempStr, s.str); String temp(tempStr); delete[] tempStr; return (temp); } ostream& operator<< (ostream& os, const String& s) { os << s.str; return (os); } istream& operator>> (istream& os, String& s) { char str[100]; is >> str; s = String(str); return (is); }
C++
복사
여기서 보면 생성자에서는 오버로딩이 되어져 const char * 형을 받는 것을 볼 수 있다.
하지만 대입 연산자에서는 무조건 인자가 String& 으로 되어있다. 하지만 실제로 써보면
#include <iostream> #include <string> using namespace std; int main(void) { string s1 = "This is String Class!"; string s2; s2 = s1; cout << s1 << endl; cout << s2 << endl; char* c; strcpy(c, "Hello dcho!"); string s3; s3 = c; cout << c << endl; cout << s3 << endl; return (0); } // result > ./a.out This is String Class! This is String Class! Hello dcho! Hello dcho!
C++
복사
위 코드를 보면 s2 대입 연산자에서 string 객체가 들어가는 것은 당연하지만 s1, s3 char* 형이 들어가는 것은 조금 이상해 보인다.
하지만 s1에 대입이 되어지는 literal constant char[]도 어떻게 보면 char* 형 이다. 그리고 s3에 들어가는 것도 char* 형 이다.
뭐지 StringClass를 보고, google형님께도 질문을 해도 답이 나오지 않았지만 jseo님께서 명쾌한 해답을 주셨다.
char* → string 변환
애초에 C++에서 String 클래스는 문자열의 처리를 목적으로 정의된 클래스이기에 C-Style의 문자열은 char* 형이 였다. C++에서는 그것을 알잘딱 해서 String 객체로 type casting을 기본적으로 해준다고 한다!
string → char* 변환
반대로도 그냥 되었으면 좋겠지만 아쉽게도 그렇게 하면 컴파일이 에러를 내뱉는다.
error: assigning to 'char *' from incompatible type 'std::__1::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >')
한마디로 변환할 수 없다! 그 이유는 자동 형변환이 안되기 때문이다.
그래서 string class에서 제공해 주는 것이 c_str() 이 멤버 함수를 지원한다.
이 함수를 이용하면 String 객체에서 char* 형 으로 변환되어 저장이 된다.

2. String 객체에 값을 넣을때 주의 할점

나는 이렇게 썼다.
std::string input; input = hollys.my_cin(); // 대충 입력 받는 함수 for(size_t i = 0; i < input.size(); i++) input[i] = toupper(input[i]); std::cout << input << std::endl; // 잘 됨
C++
복사
jji는 이렇게 사용하려고 했다.
std::string input; std::string cmd; input = hollys.my_cin(); for(size_t i = 0; i < input.size(); i++) cmd[i] = toupper(input[i]); std::cout << cmd << std::endl; // 하나도 안나옴
C++
복사
알아보니 input에 gta를 넣었을때 toupper도 되었고cmd[0] = 'G', cmd[1] = 'T', cmd[2] = 'A' 정상적으로 잘 나왔다. 하지만 cmd.size() -> 0.. 알고보니 배열처럼 막 넣기만 했지 정상적으로 값을 추가를 해주려면 += 를 해주어야 했다.
std::string input; std::string cmd; input = hollys.my_cin(); for(size_t i = 0; i < input.size(); i++) cmd += toupper(input[i]); // 수정사항 std::cout << cmd << std::endl; // 잘 됨
C++
복사
앞으로 주의 하자.