본문 바로가기
C 언어

C언어 구조체의 동적배열 사용하기 (2)

by treeCoder 2021. 2. 16.

C언어 구조체의 동적배열 사용하기를 소개한다. 1탄 보다 좀 더 발전되고, 간결하며 정돈된 느낌이 든다.

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

typedef struct Data {
    int num;
    char *name;
} Data;

typedef struct Array {
    Data **base;
    size_t size; 
    size_t count;
} Array;

void exit_if_null(void *ptr, char *msg) {
    if (!ptr) {
        printf("unexpected null pointer: %s\n", msg);
        exit(EXIT_FAILURE);
    }
}

Data *NewData(int num, const char *name) {

    Data *data = (Data *)malloc(sizeof(Data));
    exit_if_null(data, "new Data");

    data->name = (char *)malloc(strlen(name) + 1);
    exit_if_null(data->name, "new Data name");

    strcpy_s(data->name, strlen(name) + 1, name);
    data->num = num;

    return data;
}

void ClearData(Data *data) {
    free(data->name);
    free(data);
}

void PrintData(Data *data) {

    printf("No.:%d Name:%-5s\n", data->num, data->name);
}

Array *NewArray(void) {

    Array *arr = (Array *)malloc(sizeof(Array));
    exit_if_null(arr, "new Array");

    arr->base = (Data **)malloc(sizeof(Data *));
    exit_if_null(arr->base, "new Array Base");

    arr->size = 1;
    arr->count=0;
    
    return arr;
}

void ArrayPushBack(Array *arr, int num,const char *name) {

    if (arr->count == arr->size) {
        arr->size *= 2;
        arr->base = (Data **)realloc(arr->base,sizeof(Data *)*arr->size);
        exit_if_null(arr->base, "Array Push Back");
    }
    arr->base[arr->count] = NewData(num, name); 
    arr->count++;   
}

void PrintArray(Array *arr) {

    Data *data = NULL;

    for(int i=0;i < arr->count; i++) {
        data = arr->base[i];
        PrintData(data);
    }
}

void ClearArray(Array *arr) {

    Data *data = NULL;

    for(int i=0; i < arr->count; i++)  { 
        data = arr->base[i];
        ClearData(data);
    }
    free(arr->base);
    free(arr);
}

int searchArray(Array *a, char *find) { 
    int found = 0;
    int indx;

    for(int i = 0; i < a->count && !found ; i++) {
        found = strcmp(  a->base[i]->name, find ) == 0 ;
        indx = i;
    }
   
    if( !found ) indx = -1;
        
    return indx;
}

void sortArray(Array *a) {  // bubble sort
    int i, j;
    Data *tmp;

    for (i = 0; i < a->count - 1 ; i++) {
        int swapped = 0; // false
        for (j = 0; j < a->count - i -1; j++) {
              if (strcmp(a->base[j]->name, a->base[j + 1]->name ) > 0 ) {
                     tmp = a->base[j];
                     a->base[j] = a->base[j + 1];
                     a->base[j + 1] = tmp;
                     swapped = 1; // true
              }
       }
       if( swapped == 0) break; // if false, then break;
    }
}

int main(void) {   
 
    Array *arr = NewArray();
    
    ArrayPushBack(arr,1, "mango1");  // 0th
    ArrayPushBack(arr,2, "papaya2"); // 1st
    ArrayPushBack(arr,3, "apple3");  // 2nd
    ArrayPushBack(arr,4, "banana4"); // 3rd
    ArrayPushBack(arr,5, "orange5"); // 4th

    int indx = searchArray(arr, "apple3");
    if( indx > -1 ) arr->base[indx]->num += 100;

    sortArray(arr);
    PrintArray(arr);

    ClearArray(arr);
    return 0;
}

실행결과는 아래와 같다.

 

다음의 압축파일은 위의 코드를 사용해서 개인프로젝트를 만든 것이다. TCC로 컴파일 하여야 실행이된다.

무슨 이유인지, GCC로 컴파일하면 제대로 동작이 되질 않는다.

Logen_Num.zip
0.00MB

 

 GCC로 컴파일하여도 제대로 동작하는 파일도 올려 놓는다.

Logen_Num2.zip
0.00MB

댓글