7. Ç¥ÁØ C++ ¶óÀ̺귯¸® string class

À§¿¡ ¾ð±ÞµÈ String class (S°¡ ´ë¹®ÀÚÀÎ °Í¿¡ ÁÖÀÇ!)´Â Java¸¦ »ç¿ëÇÏ´Â »ç¶÷µéÀ» À§ÇÑ °ÍÀÎ ¹Ý¸é, Ç¥ÁØ C++ ¶óÀ̺귯¸®¿¡¼­ Á¦°øµÇ´Â "ÁøÂ¥" string class¸¦ ÁÖ¸ñÇÒ Çʿ䰡 ÀÖ´Ù.

string class´Â C¿¡¼­ÀÇ °¡Àå Å« ¹®Á¦Á¡ Áß ÇϳªÀÎ ¹®Àڹ迭ÀÇ ´ÜÁ¡À» ±Øº¹Çϱâ À§ÇØ ¸¸µé¾îÁ³´Ù. ¹®Àڹ迭ÀÌ ¹«Ã´ ºü¸£±ä ÇÏÁö¸¸, ¸¹Àº ´ÜÁ¡À» °®°í ÀÖ´Ù. ¹®Àڹ迭Àº ¸¹Àº ¹ö±×ÀÇ ¿øÀÎÀ̰í, À̸¦ parsingÇÏ´Â ÀÏÀº ±²ÀåÈ÷ ±ÍÂúÀº ÀÏÀÌ´Ù.

string class´Â ¹®ÀÚ¿­À» ÆÄ½ÌÇϰí, Á¶Á¤Çϴµ¥ ÇÊ¿äÇÑ ÁÁÀº ÀÎÅÍÆäÀ̽º¸¦ Á¦°øÇϰí, STL°úµµ ȣȯ°¡´ÉÇÏ´Ù. Áï, ¸ðµç STLÀÇ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ½ÇÁ¦·Î ¹®ÀÚ¿­Àº vector<char> ( ¹®ÀÚµéÀ» À§ÇÑ container ȤÀº Áøº¸µÈ ¹®Àڹ迭 ) ·Î Ãë±ÞµÉ ¼ö ÀÖ´Ù.

´ÙÀ½ÀÇ »çÀÌÆ®¿¡¼­ Âü°íÇÒ¸¸ÇÑ °ÍµéÀ» ¾òÀ» ¼ö ÀÖ´Ù:

7.1. ¿¹Á¦·Î »ìÆìº¸´Â string

stringÀ» ¸¸µå´Â °ÍÀº ½±´Ù. Creating a string is easy:
#include <string>
#include <iostream>

using namespace std;

int main()
{
    string str("Hello World!"); // ȤÀº string str = "Hello World!";
    cout << str << endl;
}

ÀÌ ÄÚµå´Â "str'¶õ stringÀ» ¸¸µé°í, "Hello World!' ¶ó´Â ³»¿ëÀ» ³ÖÀ» °ÍÀÌ´Ù. ±×¸®°í coutÀ» »ç¿ëÇÏ¿© Ç¥ÁØÃâ·Â(stdout)À¸·Î Ãâ·ÂÇÒ °ÍÀÌ´Ù.

(ÀÌÁ¦ºÎÅÍ ¸ðµç Çì´õ¿Í namespace °ü·ÃºÎºÐÀº »ý·«ÇÒ °ÍÀÌ´Ù.)

¹®ÀÚ¿­ÀÇ ºÎºÐÀ» ±¸ÇÏ´Â °Í ¿ª½Ã ½±´Ù :
string str("Hello Universe!");
string start = str.substr(0, 5);
string end = str.substr(5);

¿©±â¼­´Â ù 6±ÛÀÚ¸¦ string "start"¿¡, ³ª¸ÓÁö´Â "end"¿¡ µé¾î°¥ °ÍÀÌ´Ù.

¹®ÀÚ¿­ÀÇ ±æÀ̸¦ ¾ò±â À§Çؼ­´Â, ¾Æ·¡¿Í °°ÀÌ ÇÏ¸é µÈ´Ù.
string str("How long is this string?");
cout << "Length of string is: " << str.size() << endl;

ȤÀº ÀÌ¿Í Á¤È®È÷ ¶È°°Àº ¿ªÇÒÀ» ÇÏ´Â length() ¸¦ ½áµµ µÈ´Ù.

7.2. ¹®ÀÚ¿­À» ã±â

¹®ÀÚ¿­À» ã´Â °ÍÀº ¹®Àڹ迭º¸´Ù ÈξÀ ½±´Ù. string class´Â ¹®ÀÚ¿­À» ã´Âµ¥ È¿À²ÀûÀÎ ¸â¹ö ÇÔ¼öµéÀ» Á¦°øÇÑ´Ù. ¸ðµç ¸â¹öÇÔ¼ö´Â string::size_type À» returnÇÑ´Ù.

Ç¥ 1. ¹®ÀÚ¿­ °Ë»ö ¸â¹ö ÇÔ¼ö

¸â¹ö ÇÔ¼öÀÛµ¿ 
find() ÁÖ¾îÁø ºÎºÐ¹®ÀÚ¿­ÀÌ Ã³À½À¸·Î ³ªÅ¸³ª´Â °÷À» ã´Â´Ù 
find_first_of() find()¿Í °°À¸³ª ÁÖ¾îÁø ¹®ÀÚ°¡ óÀ½À¸·Î ³ªÅ¸³ª´Â À§Ä¡¸¦ ã´Â´Ù 
find_last_of() find first of()¿Í °°À¸³ª, ÁÖ¾îÁø ¹®ÀÚ°¡ ¸¶Áö¸·À¸·Î ³ªÅ¸³ª´Â À§Ä¡¸¦ ã´Â´Ù 
find_first_not_of() find first of() °ú °°À¸³ª ÁÖ¾îÁø ¹®ÀÚ°¡ ¾Æ´Ñ ù ¹®ÀÚ°¡ óÀ½À¸·Î ³ªÅ¸³ª´Â À§Ä¡¸¦ ã´Â´Ù 
find_last_not_of() find last of() °ú °°À¸³ª ÁÖ¾îÁø ¹®ÀÚ°¡ ¾Æ´Ñ ¹®ÀÚ¸¦ ã´Â´Ù. 
rfind() find()¿Í °°À¸³ª, ã´Â ¹æÇâÀÌ ¹Ý´ëÀÌ´Ù. (µÚÂʺÎÅÍ Ã£´Â´Ù) 
   

°¡Àå ÈçÇÑ »óȲÀº ¹®ÀÚ¿­À» ã´Â °ÍÀ̰í, ÀÌ´Â find() ÇÔ¼ö¸¦ »ç¿ëÇÏ¸é µÈ´Ù.
string str("Hello, can you find Ben?");
string::size_type position = str.find("Ben");
cout << "First occurence of Ben was found at: " << position << endl;

ÀÌ ÄÚµå´Â 'Ben'¿¡ ´ëÇØ ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏ´Â °Ë»öÀ» Çϰí, ½ÃÀÛÀ§Ä¡¸¦ 'position'¿¡ string::size_type ŸÀÔÀ¸·Î ³Ö´Â´Ù. ¸®ÅÏÇÏ´Â °ªÀÌ int°¡ ¾Æ´Ï¶ó Ưº°È÷ °í¾ÈµÈ string::size_type ŸÀÔÀ̶ó´Âµ¥ ÁÖÀÇÇ϶ó.

find_first_of() ÇÔ¼ö´Â ½ÇÁ¦ÀûÀÎ ¿¹°¡ ÇÊ¿äÇÒ °ÍÀÌ´Ù. ¾Æ·¡¿Í °°Àº »óȲÀ» º¸ÀÚ.

string s = "C++ is an impressive language.";
string::size_type pos = s.find_first_of(" .");

while (pos != string::npos) {
    cout << "Found space or dot at: " << pos << endl;
    pos = s.find_first_of(" .", pos + 1);
}

find_first_of()ÇÔ¼ö¸¦ ¾²¸é, ¿ì¸®´Â ù¹øÂ° ÀÎÀÚÀÇ ¸ðµç ¹®ÀÚ¸¦ ã°Ô µÇ°í, µû¶ó¼­ ¿©±â¼­´Â ½ºÆäÀ̽º(' ') ȤÀº Á¡('.')À» ã°Ô µÈ´Ù.

ÇÁ·Î±×·¥À» ÄÄÆÄÀÏÇØ¼­ ¾î¶»°Ô Ãâ·ÂµÇ´ÂÁö º¸¾Æ¶ó.

7.3. string tokenizer

¹®ÀÚ¿­À» °¡Áö°í ÀÚÁÖ ÇϰԵǴ ÀÛ¾÷ Áß Çϳª´Â, ¾î¶² ±¸ºÐÀÚ¸¦ °¡Áö°í ÅäÅ«µé·Î ³ª´©´Â °ÍÀÌ´Ù (tokenize). tokenizer´Â ¹®ÀÚ¿­À» find()¸¦ °è¼Ó ºÎ¸£´Â ÀÏ ¾øÀÌ ½±°Ô Á¶±×¸¸ Á¶°¢µé·Î Âɰ¶ ¼ö ÀÖµµ·Ï ÇØÁØ´Ù. C¿¡¼­´Â, ¾Æ¸¶µµ ¹®ÀÚ ¹è¿­¿¡ ´ëÇØ strtok() ¶õ ÇÔ¼ö¸¦ ½èÀ» °ÍÀÌÁö¸¸, ¹®ÀÚ¿­¿¡ ´ëÇØ¼­´Â ÀÌ·¯ÇÑ ÇÔ¼ö°¡ ¾ø´Ù. µû¶ó¼­ Á÷Á¢ ÀÌ·± ÇÔ¼ö¸¦ ¸¸µé¾î¾ß °ÚÁö¸¸, ¸î°¡Áö ÇØ°áÃ¥ÀÌ ÀÖ´Ù.

The advanced tokenizer:
void Tokenize(const string& str,
                      vector<string>& tokens,
                      const string& delimiters = " ")
{
    // ¸Ç ù ±ÛÀÚ°¡ ±¸ºÐÀÚÀÎ °æ¿ì ¹«½Ã
    string::size_type lastPos = str.find_first_not_of(delimiters, 0);
    // ±¸ºÐÀÚ°¡ ¾Æ´Ñ ù ±ÛÀÚ¸¦ ã´Â´Ù
    string::size_type pos     = str.find_first_of(delimiters, lastPos);

    while (string::npos != pos || string::npos != lastPos)
    {
        // tokenÀ» ã¾ÒÀ¸´Ï vector¿¡ Ãß°¡ÇÑ´Ù
        tokens.push_back(str.substr(lastPos, pos - lastPos));
        // ±¸ºÐÀÚ¸¦ ¶Ù¾î³Ñ´Â´Ù.  "not_of"¿¡ ÁÖÀÇÇ϶ó
        lastPos = str.find_first_not_of(delimiters, pos);
        // ´ÙÀ½ ±¸ºÐÀÚ°¡ ¾Æ´Ñ ±ÛÀÚ¸¦ ã´Â´Ù
        pos = str.find_first_of(delimiters, lastPos);
    }
}

tokenizer´Â ´ÙÀ½°ú °°ÀÌ ¾²ÀÏ ¼ö ÀÖ´Ù.
#include <string>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
    vector<string> tokens;

    string str("Split me up! Word1 Word2 Word3.");

    Tokenize(str, tokens);

    copy(tokens.begin(), tokens.end(), ostream_iterator<string>(cout, ", "));
}

À§ÀÇ ÄÚµå´Â Tokenize ÇÔ¼ö¸¦ »ç¿ëÇÏ´Â ¿¹·Î¼­, ù¹øÂ° ÀÎÀÚÀÎ str¸¦ Âɰµ´Ù. ±×¸®°í ¿ì¸®°¡ ¼¼ ¹øÂ° ÀÎÀÚ¸¦ ÁÖÁö ¾Ê¾Ò±â ¶§¹®¿¡ µðÆúÆ®·Î ¼³Á¤µÈ " "(spacebar)¸¦ ±¸ºÐÀÚ·Î »ç¿ëÇÑ´Ù. ±×¸®°í ¸ðµç element´Â tokens º¤ÅÍ¿¡ µé¾î°¡°Ô µÉ °ÍÀÌ´Ù.

¸¶Áö¸·À¸·Î Ç¥ÁØ Ãâ·Â¿¡ º¤ÅÍ Àüü¸¦ copy()ÇÔÀ¸·Î½á º¤ÅÍÀÇ ³»¿ëÀ» È­¸éÀ¸·Î º¼ ¼ö ÀÖÀ» °ÍÀÌ´Ù.

¶Ç´Ù¸¥ Á¢±Ù ¹æ¹ýÀº stringstreamÀ» »ç¿ëÇÏ´Â °ÍÀÌ´Ù. C++¿¡¼­ streamÀº Ư¼öÇÑ ±â´ÉÀÌ Çϳª Àִµ¥, ÀÌ´Â °ø¹é(whitespace)¸¦ ¸¸³¯ ¶§±îÁö Àб⸦ °è¼ÓÇÑ´Ù´Â °ÍÀÌ´Ù. µû¶ó¼­ ¾Æ·¡ÀÇ ÄÚµå´Â °ø¹éÀ» ±âÁØÀ¸·Î ¹®ÀÚ¿­À» ³ª´©°íÀÚ ÇÒ ¶§ Àß µ¿ÀÛÇÒ °ÍÀÌ´Ù.

#include <vector>
#include <string>
#include <sstream>

using namespace std;

int main()
{
    string str("Split me by whitespaces");
    string buf; // ¹öÆÛ string
    stringstream ss(str); // stringÀ» stream¿¡ ³Ö´Â´Ù

    vector<string> tokens; // wordµéÀ» ³ÖÀ» vector

    while (ss >> buf)
        tokens.push_back(buf);
}

ÀÌÁ¦ stringstreamÀº Ãâ·Â ¿¬»êÀÚ(>>)¸¦ »ç¿ë ÇÏ¿© ¹®ÀÚ¿­À» buf ¿¡ °ø¹éÀ» ¸¸³¯ ¶§¸¶´Ù ³Ö´Â´Ù. buf´Â À̸¦ Â÷·Ê´ë·Î º¤ÅÍ¿¡ push_back() ÇÑ´Ù. ±×¸®°í ÀÌÁ¦ tokens º¤ÅÍ´Â str ¿¡ µé¾îÀÖ´Â ¸ðµç ´Ü¾î¸¦ °®°Ô µÈ´Ù.