본문 바로가기
~ 2024.03/C 언어

[C 언어 기초] 문자열 문자마다 읽기

by Monett 2023. 12. 13.
반응형

K.N.King 의 C Programming - A Modern Approach 를 공부하며 내용을 정리한 글 입니다.
현재 블럭의 내용은 작성자의 의견 혹은 생각이며, 틀린 내용이 있을 수 있습니다. 지적 감사드립니다.

문자열 리터럴 

문자열 리터럴(string literal)이란 큰 따옴표로 둘러쌓인 문자의 연속체를 의미한다

문자열 리터럴 저장 방법

C는 문자열 리터럴을 문자 배열 취급을 한다.

 

C 컴파일러가 프로그램에 n 길이의 문자열 리터럴을 보게 되면 해당 문자열을 위해 n + 1 바이트를 할당해준다. 이 메모리는 해당 문자열의 문자들을 저장하고, 마지막에 한 가지 추가적인 문자인 널 문자(null character)를 넣어주어 문자열의 끝임을 알려준다. 널 문자는 비트가 전부 0인 바이트이므로 확장 비트열로 \0으로 표현한다.

 

예를 들어 문자열 리터럴 "abc"는 네개의 문자 (a, b, c, \0)를 배열에 저장한다.

문자열이 비었다면("") 널 문자 하나만 저장하고 있다.

 

문자열 리터럴이 배열로서 저장 되기 때문에 컴파일러는 이를 char* 형에 대한 포인터로 취급한다.


문자열 변수

C는 모든 문자의 일차원 배열 중 널 문자로 끝나기만 하면 문자열을 저장할 수 있다.

 

우리가 최대 80문자 정도의 문자열을 저장할 수 있는 변수가 필요하다면, 널 문자를 포함하여 81개의 문자를 갖는 배열 변수를 선언해주면 된다.

#define STR_LEN (80)

char str[STR_LEN + 1];

문자열 문자마다 읽기

scanf와 gets 모두 대부분의 프로그램에서 사용하기엔 위험하고 유연하지도 않기 때문에 대부분의 C 프로그래머들은 자신만의 입력 함수를 만든다.

 

우리의 입력 함수는 다음과 같은 문제들을 해결해주어야 한다.

  • 함수가 문자열에 내용을 저장하기 전에 공란 문자들을 생략해주어야 하는가?
  • 어떤 문자가 함수의 읽기를 중단시키는가? 개행문자? 공란문자? 아니면 다른 문자? 이 문자를 문자열에 저장해주어야하는가, 아니면 버려야하는가?
  • 만약 입력 문자열이 저장하기에 너무 크면 어떻게 처리해야 하는가? 나머지 문자들을 버려야하는가 아니면 다음번에 다시 읽기 연산 때를 위해 남겨두어야 하는가?

만약 공란 문자를 무시하지 않고, 개행 문자에서 읽기를 멈추며(저장하지 않고), 초과한 문자들을 버리는 함수가 필요하다고 하자. 함수는 다음과 같은 원형을 가질 것이다

int read_line(char str[], int n);

 

str은 입력값을 저장할 배열이고, n은 읽을 문자들의 최대 개수이다.

read_line의 반환값은 실제로 str에 저장한 문자의 개수이다.

 

read_line은 str에 저장할 공간이 남아있을 때 getchar를 호출해서 문자를 읽고 해당 문자를 str에 저장해주는 루프로 구성되어 있다. 루프는 개행문자를 읽는 순간 종료될 것이다.

int read_line(char str[], int n)
{
    int ch;
    int i = 0;

    while ((ch = getchar()) != '\n') {
        if (i < n) {
            str[i++] = ch;
        }
    }

    str[i] = '\0';    
    return i;         
}

 

i (저장한 문자의 개수)를 반환하기 전에 문자열의 끝에 널 문자를 넣어준다.

반응형