본문 바로가기
STUDY/CODING

열혈 C: 문제25-2 1번 문제

by 나비로이 2020. 3. 14.

후우... 조금...아주 조금 힘들었다.

다 작성하고 나니 조금 더 매끄럽게? 쓸 수도 있을 것 같은데 귀찮아서.,,,,

나중에 비슷한 문제 만났을때 다시 하지뭐

이 문제는 사용자가 입력한 1)문자열 길이 만큼 2)공백이 있는 문자열을 받아서 3)'단어'단위로 역순으로 출력 하는 문제이다.

몇 가지 부딪힌 문제가 있었는데

1. 문자열 길이 입력 한 후 바로 프로그램 종료됨

이유: 100을 입력했을 때, 100\n 으로 입력되기 때문에 그 다음 scanf 함수에서 \n을 받고 종료됨

-> while과 getchar 함수를 이용해 \n을 모두 읽어준다. (읽어주면 입력버퍼에서 소멸)

-> fflush 함수를 이용할 수도있지만 원칙적으로는 fflush는 출력버퍼에만 해당하기때문에, 나는 사용하지 않았다.

2. fgets 로 문장 입력시 (예를들어: "I am a cat" 입력)

I am a cat\0 까지

strlen(ptr) = 11이 된다. (마지막 널문자 제외)

((사실 입력받은건 I am a cat엔터\0 인거임))

0

1

2

3

4

5

6

7

8

9

10

I

공백

a

m

공백

a

공백

c

a

t

\0

sl은 공백을 포함, 맨 마지막 널문자를 제외한 문자열 길이로 맞추기 위해

strlen(ptr)-2 를 해주었음.

역순으로 출력해야하기 때문에 뒤에서부터 공백을 찾는 코드

그리고 그 공백의 배열 넘버 + 1부터 출력하는 코드

(여기서 printf("%s", ptr[j]) 이런식으로 짜면

맨 처음은 cat으로 잘 출력되지만 그 다음부터는 a cat / am a cat / 이런식으로 출력된다...

그래서 반복문 이용해서 문자단위로 출력했음

맨마지막

if(ptr[0]!=' ')

printf("%c", ptr[0]);

이 부분은 i 가 제일 작은 숫자 0이 되어도 j가 0+1이기 때문에

ptr[0]을 출력하지 못해서 마지막에 공백검사후 출력하도록 코딩했다. 제일 아쉬운 부분이기도 한데..일단은...뭐...

(나는 출력할 단어의 앞부분에 공백이 있는지를 검사하는 코딩을 했는데,

I 앞의 공백은 검사할 수 없다. 배열의 맨 앞부분이기 때문)

(그냥 눈으로만 보면 이해가 잘 안 되니 손코딩을 해보기 바란다.

중간중간 printf를 이용해 현재 i, j, spnum값이 얼만지 알아내면 이해 및 오류를 알아내기 쉽다.)

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    
    int length;
        
    printf("문자열의 최대길이 입력: ");
    scanf("%d", &length);
    while(getchar()!='\n');

    char * ptr = (char *)malloc(sizeof(char)* length);
    
    printf("문장 입력: ");
    fgets(ptr, length, stdin);

    int i, spnum;
    int sl = (int)strlen(ptr)-2;
    
    for(i=sl; i>=0; i--)
    {
        if(ptr[i]==' ')
        {
            spnum = i;
            for(int j=spnum+1; j<=sl; j++)
            {
                if(ptr[j]!=' ')
                    printf("%c", ptr[j]);
                else
                    break;
            }
            printf(" ");
        }
        else
            continue;
    }
    if(ptr[0]!=' ')
        printf("%c", ptr[0]);
    
    printf("\n");
    return 0;
}

 

책에 나와있는 답안은 더 심플하다.

차례대로 단어출력후, 출력한 그 값에 0을 넣어 문자열의 끝을 만들어줬기 때문...

이 답안도 배열의 맨 앞문자는 따로 출력해주고 있다.

나는 free 하는걸 까먹었다 ㅎ

그리고 사실 맨 앞부분의 공백여부 조건문은 필요가 없구나,,,,,,

나만의 코딩을 해보고 답안을 참조하기 바란다.

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    int maxlen, len, i;
    char * str;
    
    printf("문자열의 최대길이 입력: ");
    scanf("%d", &maxlen);
    getchar();
    
    str=(char*)malloc(sizeof(char)*maxlen+1);
    
    printf("문자열 입력: ");
    fgets(str, maxlen+1, stdin);
    
    str[strlen(str)-1]=0;
    len = strlen(str);
    
    for(i=len; i>0; i--)
    {
        if(str[i]==' ')
        {
            printf("%s ", &str[i+1]);
            str[i]=0;   //오 이런식의 접근은 생각 못했다...
        }
    }
    printf("%s ", &str[0]);
    free(str);
    return 0;
    
}

2020.3.12

댓글