string(문자열) 자료형의 데이터는 char(문자) 자료형의 데이터들의 배열이다.
string s = "HI!";
위와 같이 문자열 s가 정의되어 있으면, s는 문자의 배열이기 때문에 메모리상에 아래 그림과 같이 저장되고 인덱스로 각 문자에 접근할 수 있다.
끝에 있는 \0
은 문자열의 끝을 나타내는 널 종단 문자이다. 모든 비트가 0인 1바이트를 의미한다.
💡 널 종단 문자 💡
컴퓨터 프로그래밍에서 문자열 및 널 문자(\0
, ASCII에서는 NUL)로 끝나는 배열로 저장되는 문자열이다. C에서 문자열의 길이는 NUL 바이트를 검색함으로써 발견된다. 즉 NUL은 문자열의 끝을 알리는 목적으로 사용된다.
string names[4];
names[0] = "EMMA";
names[1] = "RODRIGO";
names[2] = "BRIAN";
names[3] = "DAVID";
printf("%s\n", names[0]);
printf("%c%c%c%c\n", names[0][0], names[0][1], names[0][2], names[0][3]);
names
라는 문자열 배열에 4개의 이름이 저장되어 있다. 첫번째 printf에서는 names의 첫번째 인덱스의 값인 EMMA
를 출력한다. 두번째 printf에서는 형식 지정자가 %c이다. 따라서 여기서 출력되는 것은 문자열이 아닌 문자이다. 예를 들어, names[0][1]는 names의 첫번째 값인 EMMA
라는 문자열에서 그 두번째 값인 M
이라는 문자를 의미한다. 아래 그림에서 names가 실제 메모리상에서 저장된 예시와 해당하는 인덱스를 확인할 수 있다.
사용자로부터 문자열을 입력받아 한 글자씩 출력하는 코드를 작성하면 아래와 같다. 아래 코드에서는 변수 n
에 문자열 s
의 길이를 저장하고, 해당 길이 만큼만 for 루프를 순환한다. 일일이 널 종단문자를 검사하는 것보다 효율적이다.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
string s = get_string("Input: ");
printf("Output:\n");
for (int i = 0, n = strlen(s); i < n; i++) // strlen()은 문자열의 길이를 알려주는 함수
{
printf("%c\n", s[i]);
}
}
이를 응용해서 사용자로부터 입력받은 문자열을 대문자로 바꿔주는 코드를 작성할 수 있다.
사용자로부터 입력받은 문자를 s
라는 변수에 저장하고 그 s
의 길이만큼 for문을 돌면서 각 인덱스에 해당하는 문자가 a보다 크고 z보다 작은지 검사한다(= 소문자인지 검사). 대소문자 여부는 ASCII코드 상에서의 숫자로 확인할 수 있다.
따라서 각 문자가 소문자인 경우 그 값에서 32를 뺀 후에 문자 타입으로 출력하면 대문자가 나오게 된다.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
string s = get_string("Before: ");
printf("After: ");
for (int i = 0, n = strlen(s); i < n; i++)
{
if (s[i] >= 'a' && s[i] <= 'z')
{
printf("%c", s[i] - 32);
}
else
{
printf("%c", s[i]);
}
}
printf("\n");
}