[C언어] 문자열 쪼개기(strtok)
문자열 함수중에 strtok()함수가 있는 문자열에서 특수 문자를 기준으로 문자를 쪼갤 수 있는데 이 원리를 이용하면 다양한 재밌는 실험을 할 수 있는데 그 중 CSV 데이터 형식을 간단히 계산하는 간단한 실험을 하도록 하겠습니다.
1. strtok() 함수
string.h 라이브러리 함수로서 문자열을 나누는 함수입니다. 함수는 다음과 같습니다.
strtok(문자열,"특수문자들")
문자열을 특수기호문자 공백(' '), 콤마(,), 점(.) 등 다양한 특수기호문자들로 원본 문자열에서 쪼갤 수 있습니다.
가령, 다음과 같은 표현을 했을 때를 살펴 봅시다.
p = strtok("Hello World!"," ");
p은 "Hello"라는 문자열을 추출하게 됩니다. 공백(' ')문자가 있는 위치에서 쪼개서 앞에 "Hello" 문자열을 얻게 되는 것이죠.
p = strtok("Hello World!"," ");
p = strtok(NULL," ");
이렇게 하면 첫번째는 "Hello"문자열이 등록되는데 두번째는 NULL를 하면 p은 포인터 주소를 가리킵니다. 그리고 NULL로 "Hello" 문자열을 얻고 그 다음은 NULL로 문자열을 끝을 나뉘게 되고 다음 "World!" 문자열을 기준으로 공백(' ')문자를 비교해서 추출하는데 더이상 없음으로 나머지 문자열 "World!"라는 단어를 p가 가리키게 됩니다.
설명이 좀 애매하기는 한데 실제 코딩을 실행해서 결과를 보고 이해하도록 하죠.
[코딩]
#include <stdio.h>
#include <string.h>
int main(void)
{
char a[20] = "Hello World!";
char* p;
p = strtok(a," ");
printf("%s\n", p);
p = strtok(NULL," ");
printf("%s\n", p);
return 0;
}
[결과]
결과를 보시면 대충 어떤 느낌인지 아시겠지요.
2. 실험
특수 기호로 문자열을 쪼개서 문자열을 나눈다면 데이터파일 같은 것들을 읽어와서 데이터 처리를 하는데 이용하면 괜찮을 것 같다는 생각이 들더군요. 참고로 csv 데이터 파일 같은 걸 읽어와서 이 함수를 이용하면 재밌는 계산을 할 수 있겠더군요. 실험에서는 파일 읽기까지 들어가면 너무 주제에서 벗어난 것 같고 코딩이 길어짐으로 문자열 변수에 한줄의 데이터를 콤마(,)로 구분하여 저장해 놓고 이 데이터를 구분자 콤마(,)로 쪼개여 배열 변수에 저장하여 간단히 처리하는 코딩을 만들어 보겠습니다.
char a[20] = "10,20,30,40,50";
위와 같이 문자열 변수를 만들었습니다. 콤마(,)로 쪼갠다면 다음과 같이 코딩을 해야겠지요.
p = strtok(a, ",");
while(p != NULL){
p=strtok(NULL, ",");
}
이렇게 while()문으로 순차적으로 p라는 포인터 변수에 콤마(,)쪼개진 문자열이 저장 됩니다.
각 문자열을 숫자로 변환하여 합을 구하시오.
문자열 p값을 숫자형으로 변환해야 합니다.
지난시간에 다룬 atoi()함수로 문자열을 숫자로 변환 할 수 있습니다.
p = strtok(a, ",");
while(p != NULL){
b[cnt]=atoi(p);
cnt++;
p=strtok(NULL, ",");
}
이렇게 하면 b[]배열에 문자열을 숫자로 변환한 값들이 순차적으로 저장하게 됩니다.
합구하기는 다음과 같습니다.
for(i=0;i<cnt;i++){
sum+=b[i];
}
이렇게 CSV 데이터 같은 것을 문자열 라인으로 읽어와서 구분자 콤마(,)로 쪼개고 다시 쪼개진 문자열을 숫자형으로 바꿔서 합을 구해 보았습니다.
그러면 동작이 정상적으로 이루어졌는지 실행을 시켜봐야 겠죠.
[코딩]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char a[20] = "10,20,30,40,50";
int b[5]={0,0,0,0,0};
char* p;
int cnt = 0;
int i=0;
int sum=0;
p = strtok(a, ",");
while(p != NULL){
b[cnt]=atoi(p);
cnt++;
p=strtok(NULL, ",");
}
for(i=0;i<cnt;i++){
sum+=b[i];
printf("%d\n",b[i]);
}
printf("토큰수 : %d , 합 : %d\n", cnt, sum);
return 0;
}
[결과]
3. 여러 특수기호로 쪼개기
strtok()함수는 하나의 특수기호로만 쪼개는 것이 아니라 여러개의 특수기호로 쪼갤 수 있습니다.
예제로 살펴봅시다.
[코딩]
#include <stdio.h>
#include <string.h>
int main(void)
{
char a[20] = "1-2?3,4}5";
char* p;
p = strtok(a,"-?,}");
while(p != NULL){
printf("%s\n", p);
p = strtok(NULL,"-?,}");
}
return 0;
}
strtok(a,"-?,}") 함수로 총 4개의 특수 기호들이 있는지 체크하게 됩니다. 쉽게말해서, 한개 이상을 체크할 수 있다고 생각하시면 됩니다.
[결과]
마무리
오늘은 문자열 쪼개기 실험을 했네요. post를 작성하다 보니 좀 길어져서 문자열 쪼개기 함수 구현은 못해봤네요. 호기심이 있는 분들이라면 한번 도전해 보세요.
짱짱맨 호출에 응답하였습니다.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
짱짱맨 응원에 매번 감사합니다.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
코딩을 작성해서 찾는게 빠른지 사람이 눈으로 찾는게 빠른지 시합같은거 해도 재밋겠어용. ㅋㅋ 정확도는 코딩이겠죠? ㅎㅎ
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
코딩을 따라 갈 수 없지요.
인간이 한글자 볼려고 할 때 컴퓨터는 한페이지를 이미 다 계산이 끝난 상태가 되지요.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
C도 한번 공부해봐야겠어요~
저는 자바만 해서요~ㅎㅎ
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit