본문 바로가기

알고리즘 시*련아

C++ 문자열 동적 할당

c++의 string과 getline함수의 느린 동작을 보완하기 위해서 나만의 문자열 동적 할당 함수를 작성하게 되었다

 

V.1

char* getstring(){
    char temp[STRING_SIZE];
    
    fgets(temp, STRING_SIZE, stdin);

    char* s = new char[strlen(temp)];
    strcpy(s, temp);

    return s;
}

1. 임시 배열 temp를 먼저 선언하고 

2. fgets를 통해 사용자 입력을 받아 

3. 입력의 크기만큼 새롭게 할당한 메모리에

4. 문자열을 붙여넣는다

 

이 인풋은 정상적으로 실행이 되었지만 한가지 문제가 있었다

바로 개행문자까지 저장이 된다는 것이다

$ asdfasdlkj		//인풋
-> asdfasdlkj\n		//결과물

 

그래서 마지막 개행문자를 제거해 주는 V.2를 작성했다

 

V.2

char* getstring(){
    char temp[STRING_SIZE];
    
    fgets(temp, STRING_SIZE, stdin);
    
    //마지막 개행문자 삭제
    int len = strlen(temp);
    if(temp[len-1] == '\n'){
        temp[len-1] = '\0';
        len--;
    }
    
    char* s = new char[len];
    strcpy(s, temp);

    return s;
}

여기서 새롭게 추가된것은 마지막 개행문자를 '\0' (=null) 로 바꾸어 string의 끝으로 만드는 부분이다

 

 

아주 만족스러운 나만의 인풋을 만든 나는 이 함수를 사용하여 백준 2941 크로아티아 알파벳 문제를 풀어버렸다.

완벽한 풀이에 기고만장하게 제출을 누른 나는 바로 나온 "틀렸습니다"를 보고 충격을 금치 못했다.

 

입력을 제외하고 나머지 문제풀이 부분은 전혀 문제가 없다는것을 알았기에 나의 getstring()함수에 문제가 있다는것을 알게 되었다.

 

문제는 바로 개행문자와 \0문자에 있었다

fgets는 우리가 입력하는 것 뿐만 아니라 문자열의 끝을 알리는 null 문자 '\0'을 포함한다.

 

그렇기 때문에 fgets의 buffer를 5으로 놓는다면 마지막 '\0'의 자리를 제외한 4개의 문자를 입력받는다

char* getstring(){
    char temp[5];
    
    fgets(temp, 5, stdin);
    
    int len = strlen(temp);
    if(temp[len-1] == '\n'){
        temp[len-1] = '\0';
        len--;
    }
    
    char* s = new char[len];
    strcpy(s, temp);

    return s;
}

$ abcdef	//입력
-> abcd		//출력

결과적으로 2941번 크로아티아 알파벳 문제를 풀었을때 최대 100개의 인풋을 받기 위해 STRING_SIZE를 100으로 선언하였고

실제적으로 99개의 문자만 입력이 되었으니 틀렸다고 체점이 된것이였다

 

이를 해결하기 위해서는

V.3

char* getstring(){
    char temp[STRING_SIZE];
    
    fgets(temp, STRING_SIZE + 1, stdin); // 버퍼크기에 1을 더해준다
    
    int len = strlen(temp);
    if(temp[len-1] == '\n'){
        temp[len-1] = '\0';
        len--;
    }
    char* s = new char[len];
    strcpy(s, temp);

    return s;
}

버퍼크기에 1을 더해주면 된다.

'알고리즘 시*련아' 카테고리의 다른 글

C++ 삽입 정렬 - 정렬3  (0) 2022.08.04
C++ 버블정렬 - 정렬2  (0) 2022.08.02
C++ 선택정렬 - 정렬1  (0) 2022.08.02
C++ 이중배열  (0) 2022.07.25
C++ 입력 정리  (0) 2022.07.11