C언어로 문자열 trim 함수 구현하기
trim은 문자열 양쪽의 공백들을 제거하는 함수다. 여기서 말하는 공백은 스페이스바 문자 ' '
뿐만 아니라, '\r'
, '\n'
, '\t'
문자들도 포함된다. 아래의 예시처럼 공백이 제거된다.
" hello world ! " # 입력 문자열
"hello world !" # trim 실행 후
C언어로 trim 함수 알고리듬을 구현해보자.
void trim(char* str);
C스타일 문자열을 파라미터 str로 전달받는 함수 원형이다. 반환형을 char*로 지정해서 파라미터 str의 주소를 그대로 return 해도 되지만, 여기서는 그냥 void로 설정했다.
1. 문자열 앞부분
{
char* head = str;
while (*head != '\0' && (' ' == *head || '\t' == *head || '\n' == *head || '\r' == *head)) {
++head;
}
...
head 변수를 하나 만들고 str의 맨 처음부터 시작해서, 최초로 공백이 아닌 문자의 위치를 선형탐색한다. 연산자 우선순위는 &&
가 ||
보다 먼저인 점에 유의한다.
2. ‘\0’ 문자 검색
...
char* tail = head;
while (*tail != '\0') {
++tail;
}
--tail;
...
tail 변수를 만들고 head부터 시작하여, 문자열의 끝(\0
) 을 찾는다. 그리고 나서 --tail;
을 실행하여 한 글자 이전으로 가리키게 한다.
3. 문자열 끝부분
...
while (head < tail) {
if (' ' != *tail && '\t' != *tail && '\n' != *tail && '\r' != *tail) {
break;
}
--tail;
}
...
문자열을 역으로 탐색하여, 최초로 공백이 아닌 문자를 가리키게 한다.
4. 공백 제거하기
이제 포인터 head, tail의 값이 정해졌으니, 이 범위에서 문자열을 얻을 수 있다. 새로운 문자열 메모리를 동적할당하여 그곳에 복사해도 되겠지만, 성능을 위해서 str 데이터를 변경하는 게 더 바람직할 것이다. 왜냐하면 아래와 같은 특징이 있기 때문이다. 문자열 str의 길이가 trim 처리된 길이보다 항상 크거나 같다.
...
while (head <= tail) {
*str++ = *head++;
}
*str = '\0';
}
str의 끝에는 \0
문자 넣는 것을 잊지 말자.
소스코드: https://gist.github.com/jubin-park/b68b75ea92cc795b7cb426e363cb0885
댓글
댓글 쓰기