본문

[C] 함수에서 2차원 배열 반환받기, 구분자로 문자열 나누기

자바를 주력언어로 사용하다 오랜만에 C++도 아닌 C를 하려니 적응이 잘 안된다. 대표적인 삽질이라면 malloc을 쓸 자리에 memset을 써서 한참 고생한것. 이번에는 strtok을 사용해서 문자열을 분리하려다가 이전부터 사용하던것과는 다른 설계라 괜시리 보기 싫어서 따로 함수로 만들어놓았다. 이 소스에서는 @ 구분자로 문자열을 (한번만) 분리하는것이고, 이를 좀 더 발전시킨다면 php의 split()등과 같은 형태로 만들 수 있을것 같다. 그리고 잊기전에 적어놓길. warning : incompatible implicit declaration of built-in function 은 필요한 include를 지정해주지 않았을때 생기는 오류다.

함수에서 다차원 배열을 반환하려면 동적할당을 사용하여 배열을 반환해야 하며, 아래와같이 변수를 구분해 놓으면 다차원 배열 사용시 보기가 좋다. group과 id는 문자열이므로 char*을 사용하고, ret은 문자열을 담는 배열이므로 (char*)*을 사용하였다. char** ret=(char**)malloc(2*sizeof(char*)); 은 이것의 정리를 보여주며(char* 을 2개 담는 메모리를 할당하여 이를 char**변수에 저장하라) 배열 표기법을 사용하여 포인터 사용시에 좀 더 편하게 사용할 수 있다. 사실 구조체를 사용하는게 더욱 좋지만 c구조체는 역시 별로 사용하고 싶지 않아서 이런 짓을 했다. c는 내게있어 좋은 기억이 없어서 그런지도.

문자열 함수에 대해 부가설명을 하자면, strstr함수는 msg에서 @를 찾아 처음발견한 위치의 '포인터'를 반환하며, 만약 존재하지 않았다면 NULL을 반환한다. NULL일 경우를 조건에서 제외시키고 보면 문자열의 특성상  (반환된 포인터+1) 또한 문자열로 인식된다. 좀 더 깔끔한 사용을 위하여 strdup()을 사용했는데, 이는 입력된 문자열을 복사(malloc 과정을 통해)하고 해당 포인터를 반환한다. 그리고 아래 strLength에서 포인터 놀이를 볼 수 있다. currGroup은 @가 발견된 위치, 그리고 msg는 문자열이 시작되는 위치를 가리킨다. @가 문자열 처음보다 뒤에 있으므로 포인터간의 차를 구하면 @앞까지 있는 메모리(문자) 갯수를 구할 수 있다. 그만큼을 다시 메모리를 할당해주고 strncpy로 원본 문자열에서 그 길이만큼만 복사해서 복사해준다. 

#include <stdio.h>
#include <string.h> //for str*
#include <stdlib.h> //for malloc

char** getIdAndGroup(char* msg){
    char* currGroup=strstr(msg, "@");
    char* group=NULL;
    char* id=NULL;
   
    if(currGroup!=NULL){
        int strLength=currGroup-msg;
        group=strdup(currGroup+1);
        id = (char*) malloc(strLength);
        strncpy(id, msg, strLength);
    }
    char** ret=(char**)malloc(2*sizeof(char*));
    ret[0]=id;
    ret[1]=group;
    return ret;
}

main(){
    char* msg="test@frontjang";
    char** ret=getIdAndGroup(msg);
    printf("hello, i'm %s from %s\n", ret[0], ret[1]);
}

댓글

Holic Spirit :: Tistory Edition

design by tokiidesu. powerd by kakao.