본문 바로가기
지난 학기들의 기록/C 기초

[C실습] 동적할당 유형 분석 1 - 구조체멤버에 동적할당을 이용하여 저장하기(strncpy 활용예제)

by 아메리카노와떡볶이 2020. 11. 20.
728x90
문자열을 분리하여, 구조체멤버에 동적할당을 이용하여 저장하기

man-25-1.tistory.com/57?category=940891

 

[C실습] 문자열 유형 분석 2 - 포인터배열을 사용한 strtok구현하기(문자열에서 단어 분리하기)

포인터배열을 사용한 strtok함수 구현하기 문자열 string.h 헤더파일에 내장되어있는 strtok함수는 string token 즉 문자열을 단어로 쪼개주는 함수입니다. 이번 포스트에서는 strtok함수를 C언어로 구현

man-25-1.tistory.com

지난 포스트에서, 포인터배열을 통해 문자열을 단어로 분리하는 과정을 배웠습니다. 이번 동적할당 실습부분에서는 이 과정을 좀 더 심화하여서 다루게 될 것입니다.

 

먼저 간단한 예제를 통해 오늘 배우게 될 내용을 개념적으로 학습하고, 응용해서 과제 문제까지 풀이하겠습니다. 

두개의 문자열을 입력받고, 구조체를 이용하여
문자열에 존재하는 단어와 단어의 길이를 저장하고 출력하라

구조체 틀

typedef struct word{

      char *str;

      int length;

}WORD;

문제만 봐서는 이해하기 어렵기때문에, 예시를 통해 부가적인 상세설명을 하자면 다음과 같습니다.

첫번째 문자열 = "simple is best"

두번째 문자열 = "where are you from?"

이라는 두 문자열을 입력받았을때,

첫번째 문자열은 simple, is ,best로 분리되고 각각의 길이는 5,2,4 입니다. 따라서 단어와 길이를 저장할수있는 구조체배열이 3개 필요할 것입니다.

두번째 문자열은 단어 4개 where,are,you,from? 으로 분리되고 각각의 길이는 5,3,3,5 입니다. 구조체 배열 4개가 필요하게 됩니다.

따라서 위의 예시에 대한 출력은

simple 5

is 2

best 4

============

where 5

are 3

you 3

from? 5 

가 됩니다.

그리고 제한조건은, char temp[101]이라는 하나의 배열을 통해 문자열을 두번 반복해서 입력받아야합니다.

아이디어 생각하기

이 문제를 푸는 알고리즘은 지난번의 "문자열을 단어 단위로 분리하기" 입니다. 하지만 구조체에 단어를 저장하는 과정에서 동적할당을 통해 단어를 저장한다는 점에서 의미가 있습니다.

저는 이 문제를 처음 접했을때, 두가지 질문이 떠올랐는데 

첫번째는 구조체배열을 동적할당을 통해 선언해야하는데, 문자열을 입력받는 시점에서 어떻게 단어의 개수를 알까?

두번째는 각각 단어를 분리하면서 단어의 길이는 어떻게 구해야할까?

입니다. 

 

첫번째에 대한 해답은, 문자열을 분리하는 과정에 있습니다. 단어를 구분할때 공백을 기준으로 구분하기때문에 문자열에 존재하는 공백개수를 구해서 단어의 개수를 구하고, 단어의 개수만큼 구조체배열을 동적할당해주면 됩니다.

두번째에 대한 해답은 쉬웠습니다. 단어를 분리할때 start,end 인덱스를 사용했었는데 단순히 end-start 연산으로 단어의 길이를 구할 수 있었습니다.

 

위의 내용을 바탕으로 코드를 작성해보겠습니다.

풀이코드

출력 값

 

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
#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct word {
    char* str;
    int length;
}WORD; //단어를 저장할 구조체배열
int main() {
    char temp[101], * ptemp;
    int temp_len = 0,space=0,word_cnt=0;
    int start = 0end = 0,p_idx=0;
    for (int i = 0; i < 2; i++) {//문자열 2개를 입력받기위해 2번 반복
 
        gets(temp);
        temp_len = strlen(temp);
        //공백개수를 통해 -> 단어 개수 구하기
        for (int j = 0; j < temp_len; j++) {
            if (temp[j] == ' ') space++;
        }
        word_cnt = space + 1;// 단어의 개수는 공백개수 +1
 
        //단어개수만큼 WORD구조체 동적할당하기
        WORD* p = (WORD*)malloc(sizeof(WORD) * word_cnt);
 
        //문자열의 단어들을 구조체배열에 저장하기
        start = 0;
        ptemp = temp;
        p_idx = 0;
        for (int j = 0; j <= temp_len; j++) {
            if (temp[j] == ' ' || temp[j] == NULL) {
                end = j;
                p[p_idx].str = (char*)malloc(sizeof(char* (end - start + 1));
                strncpy(p[p_idx].str,ptemp, end - start);
                p[p_idx].str[end - start] = NULL;
                
                ptemp = ptemp + end - start + 1;
                //길이넣기
                p[p_idx].length = end - start;
 
                p_idx++;
                start = end + 1;
            }
        }
        for(int k=0;k<p_idx;k++){
        printf("%s %d\n", p[k].str, p[k].length);
        }
        for (int t = 0; t < p_idx; t++) {
            free(p[t].str);//다 쓴 메모리는 반납
            
        }
        free(p);
    }
    
    return 0;
}
cs

 

실습에서는 길이를 구하는 것으로 문제를 주었지만, 분리된 단어들을 가지고  문자열에서 단어가 나타나는 횟수를 구한다거나 구조체의 length처럼 단어의 길이가 아니더라도, 단어의 모음개수를 저장할수도 있는등 다양하게 응용이 가능합니다. 이런 부분을 고려하면서 공부하면 도움이 많은 도움이 될 것 입니다.

개념을 응용해서 과제를 해결해보자 !

위의 과정을 응용해서 푼다면 조금 복잡해졌지만 천천히 한줄씩 써나가면 풀수있을 것입니다. 이 문제는 따로 풀이과정없이 코드만 남겨두겠습니다 . 각자가 해결해보세요 !!

문제코드에 질문등은 댓글이나 DM을 주시면 답변드리겠습니다. 

풀이코드

 

colorscripter.com/s/sEzBh7I

 

공유된 코드 - Color Scripter

저작권자 : u_hock@naver.com

colorscripter.com

 

728x90

댓글