[C++] 문자열 파싱

E woo·2023년 6월 23일
1

개발 일기

목록 보기
12/15

C++ 에서 문자열을 파싱하는 (자르는) (토큰화하는) 방법을 정리해보자.

find 와 substr 이용

find()

문자열변수.find("검색할 문자열");
// 성공 : 찾은 하는 문자열의 첫 번째 인덱스 주소 반환한다.
// 실패 : string::npos 를 반환한다.
int main()
{
    string s = "Good Morning";

    int a = s.find("Good");
    int b = s.find(" ");
    int c = s.find("Morning");

    cout << a << " " << b << " " << c;

    return 0;
}

substr()

문자열변수.substr(시작할 위치, 길이);
// 시작할 위치로부터 길이 만큼의 문자열을 잘라낸다.
// 만약 길이를 생략할 경우 문자열의 끝까지 다르게 된다.
int main()
{
    string s = "Good Morning";

    string a = s.substr(0, 4);
    string b = s.substr(4, 1);
    string c = s.substr(5);

    cout << a << "\n";
    cout << b << "\n";
    cout << c << "\n";

    return 0;

위의 2개의 함수 find, substr 를 이용해 문자열을 자르는 것이 가능하다.

#include <string>
#include <iostream>

using namespace std;

int main()
{
    string s = "Good Morning";
    s += " "; // 문자열의 마지막에 공백 추가
    string delimiter = " "; // 구분자 

    int cur_pos = 0;
    int pos;
    while ((pos = s.find(delimiter, cur_pos)) != string::npos)
    {
        int len = pos - cur_pos;
        string result = s.substr(cur_pos, len);
        cout << result << "\n";
        cur_pos = pos + 1;
    }

    return 0;
}


문자열의 마지막의 공백 (구분자) 을 추가하지 않을 시 첫번째 공백을 만나고 Good 을 출력한 뒤
더 이상 문자열의 공백이 존재하지 않으므로 Morning 을 출력하지 못하고 끝나게 된다.

벡터 활용

#include <string>
#include <iostream>
#include <vector>

using namespace std;

int main()
{
    string s = "Good Morning";
    s += " ";
    string delimiter = " ";
    vector<string> my_v;

    int cur_pos = 0;
    int pos;
    while ((pos = s.find(delimiter, cur_pos)) != string::npos)
    {
        my_v.push_back(s.substr(0, pos));
        s.erase(0, pos + delimiter.length());
    }

    for (auto i : my_v)
    {
        cout << i << "\n";
    }

    return 0;
}



getline 과 istringstream 사용

sstream

문자열에 여러 자료형이 들어있거나 파싱하는 작업이 필요할때 사용하는 라이브러리로

istringstream

입력 스트림으로 문자열 안의 공백과 "\n" 을 기준으로 여러 개의 다른 형식으로
차례대로 분리할 때 사용한다.

#include <iostream>
#include <typeinfo>
#include <sstream>

using namespace std;

int main()
{
    string s = "Hello My Age is 25";
    istringstream iss(s);
    string s1, s2, s3, s4;
    int age;
    iss >> s1 >> s2 >> s3 >> s4 >> age;

    cout << s1 << "\n";
    cout << s2 << "\n";
    cout << s3 << "\n";
    cout << s4 << "\n";
    cout << age << "\n";

    return 0;
}

반복문으로 사용 시 자료형에 맞는 데이터가 없을 때까지 실행된다.

#include <iostream>
#include <typeinfo>
#include <sstream>

using namespace std;

int main()
{
    string s = "22323Hello";
    istringstream iss(s);

    int n;

    while (iss >> n)
        cout << n << "\n";

    return 0;
}

ostringstream

출력 스트림으로 문자열을 조립하거나 특정 형식을 문자열로 변환하기 위해 사용한다.

#include <iostream>
#include <typeinfo>
#include <sstream>

using namespace std;

int main()
{
    ostringstream oss;
    string s1 = "Hello";
    string s2 = "My";
    string s3 = "Name";
    string s4 = "is";
    int age = 25;
	
    // 문자열을 조립
    oss << s1 << " " << s2 << " " << s3 << " " << s4 << " " << age;
    cout << oss.str(); // 만든 문자열을 가져옴
}

stringstream

입출력 스트림으로 입력과 출력에 대해 모두 사용 가능하다.
istringstream 과 ostreamstring 대신 stringstream 사용

#include <iostream>
#include <typeinfo>
#include <sstream>

using namespace std;

int main()
{
    string s = "22323Hello";
    stringstream iss(s);

    int n;

    while (iss >> n)
        cout << n << "\n";

    stringstream oss;
    string s1 = "Hello";
    string s2 = "My";
    string s3 = "Name";
    string s4 = "is";
    int age = 25;

    oss << s1 << " " << s2 << " " << s3 << " " << s4 << " " << age;
    cout << oss.str();
}

sstream 라이브러리를 통해 원하는 구분자를 통한 문자열 파싱이 가능하다.

이전 문자열 입력에서 보았듯이 getline 을 통해 공백이나 '\n' 이 아닌 다른 문자열 기준으로
구분이 가능하다.

https://velog.io/@sw801733/C-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%9E%85%EB%A0%A5-%EB%B0%9B%EA%B8%B0

#include <iostream>
#include <string>
#include <typeinfo>
#include <sstream>

using namespace std;

int main()
{
    string s = "My,Age,is,25";
    stringstream ss(s);

    string token;
    while (getline(ss, token, ','))
    {
        cout << token << "\n";
    }
}

공백이 포함된 구분자 (", ") 일 경우

#include <iostream>
#include <string>
#include <typeinfo>
#include <sstream>
#include <algorithm>

using namespace std;

int main()
{
    string s = "My, Age, is, 25";
    stringstream ss(s);

    string token;
    while (getline(ss, token, ','))
    {
    	// 공백 제거
        token.erase(remove_if(token.begin(), token.end(), ::isspace), token.end());
        cout << token << "\n";
    }
    return 0;
}
profile
뒘벼

0개의 댓글