무슨 일로 C 하셨습니까?

[C] 문자열 다루기::문자열 합성 본문

C - 이걸 굳이?/유틸리티

[C] 문자열 다루기::문자열 합성

OJJJ 2020. 8. 25. 22:02

C에도 기본적으로 제공되는 함수들이 매우 많아서 몇개의 헤더파일만 포함시켜도 다양한 함수를 사용할 수 있다.

 

그런데 난 굳이 직접 만들어서 사용할 것이다. 최소한의 헤더만을 사용해서

 

이번엔 그 대상을 문자열로 하겠다.

 

실제로 많은 데이터를 문자열로 다루는데 문자열 함수가 생각보다 많이 불친절하다고 느꼈기 때문에 직접 만들어 쓰겠다. 그 시작은 문자열 합성함수이다.


시작은 이름없는 함수 선언부터 시작한다.

char* f(char* HeadString, char* TailString) {
    return NULL;
}

두 문자열을 합해서 반환하는 함수를 구현하겠다.

순서는 당연히 head-tail순이다. 

 

    int HeadLen = StringLength(HeadString);
    int TailLen = StringLength(TailString);

    char* result = (char*)malloc(sizeof(char) * (HeadLen + TailLen + 1));

각 문자열의 길이를 구해서 최종 반환할 문자열의 메모리를 할당하겠다.

메모리 할당 크기에 1을 더하는건 종료문자를 위해서이다.

 

문자열의 길이를 구하는 함수는 이전에 구현한

// 문자열의 길이를 알아내는 함수
int StringLength(char* str) {
    for (int i = 0;; i++) {
        if (str[i] == 0) return i;
    }
}

위 함수를 사용하겠다.

 

 

 

새로 할당한 문자열 변수에 각각의 문자열의 문자들을 넣어주면된다.

    for (int i = 0; i < HeadLen; i++) {
        result[i] = HeadString[i];
    }
    for (int i = 0; i < TailLen; i++) {
        result[HeadLen + i] = TailString[i];
    }
    result[HeadLen + TailLen + 1] = 0;
    
    return result;

문자열의 맨 마지막에 종료문자를 넣어주는걸 잊지 말도록 하자

 

함수의 최종 코드는 다음과 같다

char* StringAdd(char* HeadString, char* TailString) {

    int HeadLen = StringLength(HeadString);
    int TailLen = StringLength(TailString);

    char* result = (char*)malloc(sizeof(char) * (HeadLen + TailLen+1));

    for (int i = 0; i < HeadLen; i++) {
        result[i] = HeadString[i];
    }
    for (int i = 0; i < TailLen; i++) {
        result[HeadLen + i] = TailString[i];
    }
    result[HeadLen + TailLen + 1] = 0;
    
    return result;
}

이 함수가 정상 작동하는지는 직접 테스트해보길 바란다

 

문자열을 담기위해 배열을 동적으로 할당하였으니 free()를 통해서 메모리를 해제하는 것을 잊지말자


두 문자열을 단순히 합할 수 도 있지만 특정 부분만을 합하고 싶을 수도 있다.

 

네 가지 경우를 생각해볼 수 있겠다.

1. 단순히 두 문자열을 합하는 경우

2. 앞 문자열의 특정 위치에 뒷 문자열을 더하는 경우

3. 앞 문자열에 뒷 문자열의 일부를 더하는 경우

4. 앞 문자열의 특정 위치에 뒷 문자열의 일부를 더하는 경우

 

이 각각의 경우 함수의 파라미터를 더해주어 반복문에 변화를 주면 되겠다.

 

2. 앞 문자열의 특정 위치에 뒷 문자열을 더하는 경우

char* StringAdd2(char* HeadString,int CopyPoint , char* TailString) {

    int HeadLen = StringLength(HeadString);
    int TailLen = StringLength(TailString);

    if (CopyPoint >= HeadLen) {
        printf("wrong point\n");
        return NULL;
    }
    HeadLen = CopyPoint;

    char* result = (char*)malloc(sizeof(char) * (HeadLen + TailLen + 1));

    for (int i = 0; i < HeadLen; i++) {
        result[i] = HeadString[i];
    }
    for (int i = 0; i < TailLen; i++) {
        result[HeadLen + i] = TailString[i];
    }
    result[HeadLen + TailLen + 1] = 0;

    return result;
}

뒷 문자열을 붙이려를 지점이 원래 문자열의 길이보다 길면 에러를 처리해주겠다.

 

3. 앞 문자열에 뒷 문자열의 일부를 더하는 경우

char* StringAdd3(char* HeadString, char* TailString, int CopyLength) {

    int HeadLen = StringLength(HeadString);
    int TailLen = StringLength(TailString);

    if (CopyLength >= TailLen) {
        printf("wrong length\n");
        return NULL;
    }
    TailLen = CopyLength;

    char* result = (char*)malloc(sizeof(char) * (HeadLen + TailLen + 1));

    for (int i = 0; i < HeadLen; i++) {
        result[i] = HeadString[i];
    }
    for (int i = 0; i < TailLen; i++) {
        result[HeadLen + i] = TailString[i];
    }
    result[HeadLen + TailLen + 1] = 0;

    return result;
}

 

 

4. 앞 문자열의 특정 위치에 뒷 문자열의 일부를 더하는 경우

char* StringAdd4(char* HeadString, int CopyPoint, char* TailString, int CopyLength) {

    int HeadLen = StringLength(HeadString);
    int TailLen = StringLength(TailString);

    if (CopyPoint >= HeadLen) {
        printf("wrong point\n");
        return NULL;
    }
    HeadLen = CopyPoint;

    if (CopyLength >= TailLen) {
        printf("wrong length\n");
        return NULL;
    }
    TailLen = CopyLength;

    char* result = (char*)malloc(sizeof(char) * (HeadLen + TailLen + 1));

    for (int i = 0; i < HeadLen; i++) {
        result[i] = HeadString[i];
    }
    for (int i = 0; i < TailLen; i++) {
        result[HeadLen + i] = TailString[i];
    }
    result[HeadLen + TailLen + 1] = 0;

    return result;
}

 

각 경우에 대해서 반복되는 내용이 많기 때문에 그렇게 어렵지 않다.

 

 

    char* a = "abcdefg";
    char* b = "123456789";

    char* c = StringAdd1(a, b);
    char* d = StringAdd2(a, 3, b);
    char* e = StringAdd3(a, b, 4);
    char* f = StringAdd4(a, 3, b, 4);

그런데 경우에 따라서 함수를 다르게 호출하는게 여간 불편한게 아니다

어떤함수가 1번인지 2번인지 외우기란 쉽지가 않다.

 

이를 해결해 볼 방법을 찾아야겠다.

 

 

Comments