«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

Code Run

C, CPP 공백을 포함한 문자열 split하기 본문

코딩 tip

C, CPP 공백을 포함한 문자열 split하기

comkiwer 2018. 1. 4. 18:24
[ 방법 1 : C에서 문자열을 단어로 나누기- naive 구현] 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
split string C_version 01
comkiwer
*/
#include <stdio.h>
#include <string.h>
#define LM 100
 
char str[LM+1];             /// 입력 문자열
char word[LM+1][LM+1];      /// 분리된 단어를 저장할 배열
int wcnt;                   /// 분리된 단어의 갯수
 
int main(){
    freopen("in.txt""r", stdin);
    int i, j, len;
    /// gets(str);          /// gets() 또는 fgets()로 입력
    fgets(str, LM, stdin);  /// 최대 LM - 1개의 문자가 입력된다.
    len = strlen(str);      /// 1이상 LM - 1개 이하의 문자가 입력되었다고 가정
 
    if(str[len-1]=='\n')    /// fgets 함수는 '\n'까지 입력
        str[--len] = 0;
   if(str[len-1]=='\r')    /// fgets 함수는 '\r'도 입력 - only window
       str[--len] = 0;
 
    i = j = 0;
                            /// 문자열 처음에 등장하는 공백 제외시키기
    while(i<len && str[i]==' '++i;
    for(;i<len;++i){
        if(str[i] != ' '){  /// 공백이 아닌 경우
            word[wcnt][j++= str[i];
        }
                            /// 연속된 공백과 문자열 끝의 공백 제외시키기
        else if(str[i+1]!=' '&& str[i+1]){
            word[wcnt++][j] = 0;
            j = 0;
        }
    }
    word[wcnt++][j] = 0;
 
    for(i=0;i<wcnt;++i) puts(word[i]);
 
    return 0;
}
 
cs


[ 방법 2 : C에서 문자열을 단어로 나누기- strTok 구현] 
*** 주의 : 원본 문자열이 손상된다. 따라서 원본문자열을 재사용하고자 하는 경우 복사해서 사용한다. *** 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
simple strTok implement
comkiwer
*/
#include <stdio.h>
 
const int LM = 110;
char str[LM], word[LM][LM];
int wCnt;
 
int strLen(char*s, int i=0){
    while(s[i]) ++i;
    if(i && s[i-1]=='\n') s[--i] = 0;
    if(i && s[i-1]=='\r') s[--i] = 0;
    return i;
}
 
void strCopy(char*to, char*from){
    while((*to++ = *from ++ ));
}
 
char* strTok(char*ptr, char delim = ' '){
    static char*p;                  /// 직전 탐색 위치를 유지하기 위하여 static 사용
    if(ptr) p = ptr;                /// 새로운 문자열이 시작된 경우
    while(*&& *p==delim) ++p;     /// 구분자가 아닌 첫 문자의 위치 찾기
                                    /// trim leading or tailing or contiguous space
    if(!*p) return NULL;            /// 입력 문자열 탐색이 끝남
 
    for(ptr=p;*&& *p!=delim;++p); /// 현재 단어의 끝 찾기
    if(*p) *p++ = 0;                /// 입력 문자열 끝이 아니라면 단어의 끝 표시
    return ptr;
}
 
void split(){
    strLen(str);                    /// 입력 문자열 끝의 '\n', '\r' 제거
    char*token = strTok(str);
    while(token){
        strCopy(word[wCnt++], token);
        token = strTok(NULL);
    }
}
 
void output(){
    for(int i=0;i<wCnt;++i) puts(word[i]);
    puts("");
}
 
int main(){
    freopen("input.txt""r", stdin);
    for(int i=0;i<1;++i){
        gets(str);
        wCnt = 0;
        split();                    /// 문장을 공백을 구분자로 단어로 나누기
        output();
    }
    return 0;
}
 
cs




[ 방법 3 : C에서 문자열을 단어로 나누기 - 라이브러리 strtok이용]
*** 주의 : 원본 문자열이 손상된다. 따라서 원본문자열을 재사용하고자 하는 경우 복사해서 사용한다. *** 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
split string C_version 02
comkiwer
use strtok() function
*/
#include <stdio.h>
#include <string.h>
#define LM 100
 
char str[LM+1];             /// 입력 문자열
char word[LM+1][LM+1];      /// 분리된 단어를 저장할 배열
int wcnt;                   /// 분리된 단어의 갯수
 
int main(){
    /// freopen("in.txt", "r", stdin);
    int i, len;
    char* token;
    /// gets(str);          /// gets() 또는 fgets()로 입력
    fgets(str, LM, stdin);  /// 최대 LM - 1개의 문자가 입력된다.
    len = strlen(str);      /// 1이상 LM개 이하의 문자가 입력되었다고 가정
 
    strtok(str, "\r\n");    /// '\r'또는'\n' 제거
 
    token=strtok(str," ");  /// str문자열 시작부터 공백이 아닌 처음 위치(*sp)를 찾고
                            /// 그 이후등장하는 첫 공백 위치(*ep)를 찾아
                            /// 그 값을 '\0'로 하고 sp를 반환한다.
    while(token){
        strcpy(word[wcnt++], token);
token = strtok(NULL" ");
                            /// strtok함수의 첫 인자를 NULL로 주면 이전에 찾은
                            /// ep위치 다음부터 공백이 아닌 처음 위치를 찾는다.
                            /// 공백이 아닌 위치를 찾지 못하면 NULL을 리턴 한다.
    }
    for(i=0;i<wcnt;++i) puts(word[i]);
 
    return 0;
}
 
cs




[방법 4 : CPP에서 문자열을 단어로 나누기 - stringstream]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
split string CPP_version 01
comkiwer
use stringstream
*/
/// #include <bits/stdc++.h>
#include <cstdio>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
 
int main(){
///    ios_base::sync_with_stdio(false); /// 빠른 입출력을 위하여 싱크를 포기
///    freopen("in.txt", "r", stdin); /// c의 입출력 함수와 혼용하면 입출력이 엉킬 수 있다.
    string s, w;
    vector<string> word;
    getline(cin, s);                     /// 공백을 포함한 문자열 입력
    for(stringstream sts(s);(sts>>w);){  /// 문자열 s로 만들어진 문자열 스트림 sts생성
                                         /// 문자열 스트림 sts를 이용하여 한 단어씩 w에 입력
                                         /// sts에 남은 단어가 없다면 NULL 반환
        word.push_back(w);               /// 단어 w를 word에 추가
    }
    for(vector<string>::iterator it = word.begin();it!=word.end();++it)
        cout<<*it<<"\n";                 /// endl은 속도가 많이 느림
    return 0;
}
 
 
cs