본문 바로가기
컴퓨터 공학/C, C++

[ C ] 문자열 함수 이해하기1_C 스타일 문자열이란? / 문자열 길이 구하기

by hahehohoo 2020. 7. 21.
반응형

 

C언어 문법 C 스타일 문자열이란?

 

 

■ C 스타일 문자열 개념

기본 자료형 배울 때 가장 먼저 언급하는 부분이 그 자료형의 크기(표현할 수 있는 범위)입니다. 기본 자료형의 크기는 특정 플랫폼마다 항상 고정되어 있습니다. 

 

int num = 4 // 4바이트 (32bit)

double num2 = 1.2 //8바이트 (64bit)

 

이런 식으로 말이죠. 그럼 다음 문장을 대입할 변수 크기는 얼마로 설정하면 될까요?

"I have no idea at all"

 

일단 저장하고 싶은 데이터는 문장입니다. 여러 문자가 모인 문자열인거죠. 다른 프로그래밍 언어를 배운적이 있는 분이라면 문자열을 표현할 수 있는 자료형 Stirng(JAVA) 생각날 수도 있을 것입니다. 하지만 C언어에는 문자열을 표현할 수 있는 따로 자료형이 없습니다. 그래서 여러 문자를 나타내어 문자열처럼 보이게 해야합니다. 그 방법들 중 하나로 배열이 가장 좋습니다. 그래서 이런 식으로 작성할 수 있죠. 

 

char str[글자수]; 

 

문자를 표현하는 char형 배열을 선언하면 됩니다. 그럼 문자열의 길이를 알고 싶다면 배열의 길이 구하면 되겠네요. 

 

하지만 여기서 문제가 발생합니다. C언어에서는 배열만으로 배열의 길이를 구할 수 없기 때문입니다. 

그래서 프로그래머들은 여러가지 방법들을 고안했는데요. 그 중 하나는 배열의 길이를 상수(NUM_CHARS)로 따로 선언하는 것입니다. 아래처럼 말이죠. 

 

void print_string(void)
{
    char chars[] = "I have no idea at all";
    const size_t NUM_CHARS = 21;
    
    size_t i;
    for(i = 0; i < NUM_CHARS; ++i){
    	printf("%c", chars[i]);
    }
}

 

 

하지만 이렇게 문자열을 관리하면 실수가 생길 가능성이 많습니다. 문자열이 바뀔 때마다 상수의 값을 수동으로 직접 수정해줘야 하니까요.

굉장히 비효율적입니다. 

 

 

 

 


■ C언어 문자열 길이 구하기

 

그럼 어떻게 문자열 길이를 구해야 할까요? 배열로 만들기 위해 char[] 를 사용하되 그 문자열이 끝나는 위치에 특수한 문자를 두면 됩니다. 

바로 널 문자(null character)입니다. (널 포인터 아님) 그래서 C 스타일 문자열이라 하면 널 문자로 끝나는 char 배열을 말합니다. 이렇게 char 배열로 문자열을 표현하면 가장 최소한의 메모리를 사용한다는 장점이 있습니다. 한 가지 데이터형으로 문자열과 길이를 다 표현할 수 있기 때문입니다. 

 

char null_char = '\0';

 

0은 숫자 영, \는 이스케이프 문자입니다. 

아스키 코드로 0이라 char null_char = 0; 으로도 작성 가능합니다. 

하지만 의미를 명확하게 하려면 '\0'로 작성하는 것이 좋습니다. 

 

 

'No idea'를 메모리에 넣으면

이렇게 배열의 끝을 알 수 있으면 다음과 같은 순서로 길이를 구할 수 있습니다. 

 

1 char 배열의 요소를 처음부터 차례대로 읽는다

2 널 문자를 만나면 멈춘다

3 여태까지 총 몇 개의 char를 방문했는지 그 카운터를 반환

 

size_t get_string_length(const char* str)
{
    size_t i;
    for(i = 0; str[i] != '\0'; ++i){
    
    ...
    
    }
    return i;
}

 

 


 

 

하지만 이 방법으로는 배열을 끝까지 훑어야 (O(n)) 한다는 단점이 있습니다. 

더 효율적인 방법은 없을까요? 바로 포인터 개념을 이용하면 됩니다. 

참고할만 한 글: 포인터란?

 

size_t get_string_length(const char* str)
{
    size_t count = 0;
    const char* p = str;
    
    while(*p++ != '\0'){
    	++count;
    }
    return count;
}

포인터 변수(배열의 주소값)을 매개변수로 전달하면 함수 안에서 복사합니다. 그리고 복사한 배열 포인터의 값을 하나씩 꺼내어 0인지 비교합니다. 참일 때마다 count가 1씩 증가하다가 0을 만나면 반목분이 종료되면서 count를 반환합니다. count의 값이 배열의 길이라고 할 수 있습니다. 

문자열 길이 구하는 함수

사실 문자열 길이를 쉽게 구하는 함수가 따로 있습니다. 바로 strlen입니다. 

size_t strlen(const char* str);

 

이 함수는 문자열(str)의 길이를 반환해줍니다. 널 문자는 길이에 포함하지 않습니다. 

 

int main(void)
{
   char str[]="123456789";
   printf("%u \n", strlen(str)); // 문자열 길이 9 출력됨.
   ...
}

 

참고로 size_t은 unsigned int를 의미합니다. 

그래서

size_t len;

unsigned int len;

이 둘은 동일하므로 서식 문자 '%u'를 사용할 수 있습니다. 

 

 

 

더보기

이후 추가할 내용

들어가는 위치가 달라질 뿐

바꾸지 않아도 되는거는 2데이터 섹션

2는 맨앞에 꼭꼮꼮ㄲ 

 

...라는 건 나는 모르는 값인데 어째든 넘아세요. 

const char[str] ="

abc...fksmswj fksm

 

가끔 하는 실수1

너 따로따로 부르려는 거지 null 안넣을꺼야

그러다가 lenstr 읽어버리면 내꺼 아닌 메모리까지 쭉읽다가 엉뚱한 결과 나옴

 

아래와 같은 실수 많이함. 

무한 루프 걸릴 수도 있고 

함부로 숫자 넣지마라. 

 

 

 

 

 

 

 

-----------------------------------

C언어 문법 총정리

목록 보러가기 

-----------------------------------

 

 

 

 

반응형


댓글