본문 바로가기
작업/Programming

C언어 특정 문자를 기준으로 문자열을 나누고 역순으로 출력

 

 

띄어쓰기가 포함된 문자열을 입력받고

입력된 값의 단어들만 따로 역순으로 출력시키는 코드입니다.

(ex. hello world 입력 시 olleh dlrow 출력)

 

    char str[100];
    printf("한 줄의 문장을 입력하세요 = ");

    fgets(str, sizeof(str), stdin);


    //문자 기준 자르기, char *strtok(char *String, char const *ch);
    char *pt = strtok(str, " "); //공백 문자가 있는 값을 포인팅

    //자를 문자열이 더이상 없다면 NULL 반환
    while(pt != NULL){ 
        for(int i = strlen(pt)-1; i>-1; i--){
            if(pt[i] == '\n') continue;
            printf("%c", pt[i]);
        }
        printf(" ");
        pt = strtok(NULL, " ");
    }
    

 

문자열 내에서 특정 문자를 찾아 분리하는 문자열 함수 strtok()를 사용했습니다.

 

strtok()의 인자는 2개가 있습니다.

1. 문자열이 저장된 배열 공간을 인자로 받습니다.

2. 분리할 기준이 되는 문자를 인자로 받습니다.

 

코드에서 분리 기준은 공백 문자 " "로 지정했습니다.

문자열 str 내에서 공백 문자는 총 5구간이 있습니다.

 

 

처음 공백 구간을 기준으로 어떻게 진행되는지 알아보겠습니다.

" I've compiled "사이에 공백 문자가 있습니다.

 

 

 char *pt = strtok(str, " "); 는 첫 공백 문자 위치를 포인팅 합니다.

공백 문자가 있는 위치는 NULL(\0)로 변경됩니다.

 

포인팅 된 값을 출력하게 된다면 공백 문자 이전까지의 문자열은 I've가 출력됩니다.

공백 문자를 기준으로 문자열이 분리된 것입니다.

 

 

이후에 사용되는 strtok()의 첫 번째 인자로는 무조건 NULL을 받습니다.

그래야 처음 분리된 값 이후부터 다시 탐색해서 분리할 수 있습니다.

 

 

문자열의 마지막은 NULL로 저장되어 있기 때문에 strtok() 함수로 문자를 찾아낼 수 없습니다.

그럴 때는 strtok() 함수의 결과로 NULL이 반환됩니다.

 

 

그리고 마지막으로 구분된 문자열 다음인 "presentation\0"을 포인팅 하게 됩니다.

 

 

반복문은 분리된 문자열을 거꾸로 출력하는 역할을 합니다.

while문의 조건으로 strtok() 함수의 반환 값이 NULL일 경우 종료됩니다.

위에서 설명했듯이 NULL을 반환한다는 것은 더 이상 찾을 수 있는 문자가 없다는 의미입니다.

 

 

 

for문은 반복 인자로 (분리된 문자열의 크기)-1을 가져옵니다.

처음 분리된 문자열은 "I've"입니다. strlen() 함수의 특성상 문자열의 크기는 마지막 NULL도 포함합니다.

그래서 strlen()으로 5가 반환됩니다.

 

 

문자열이 저장된 인덱스는 0~4이기 때문에 불필요한 접근을 없애기 위해 -1 합니다.

 

 

 if(pt[i] == '\n') continue; 구문은 마지막 문자열을 한 줄로 출력하기 위해 삽입하였습니다.

마지막 문자열은 "presentation\0"입니다.

 

 

strtok() 함수로 NULL이 반환된 시점에서의 포인터는 마지막 문자열 모두를 다룰 수 있습니다. 

그렇기 때문에 strlen() 함수로 크기를 반환받게 되면 13을 반환받습니다.

 

 

문자열이 저장된 인덱스는 0~11입니다.

하지만 이전 문자열처럼 strlen()-1을 적용한다면 인덱스는 12까지 접근이 가능해지며

인덱스 12에 있는 값은 "\0"이기 때문에 출력 시 한 줄 띄어지는 현상이 발생합니다.

 

 

결과 출력은 한 줄로 표시되기를 원하는데,

마지막 문자열의 역만 한 줄 띄워져서 출력되어버리는 것입니다.

이것을 방지하기 위해 "\0"에 접근할 시에는 continue로 아무 작업 없이 다음 인덱스를 처리하게 만든 것입니다.

 

-끝-