cs50 3강 문자열
문자열이란
말 그대로 여러개의 char이 결합된 형태이다.
즉 배열와 마찬가지로 메모리에 순차적으로 올려놓을 수 있기 때문에, 대부분의 c언어 책과 강의에서는 문자열과 배열을 거의 동시에 다루거나 바로 다음번 챕터에 배치해두는 경우가 많다.
하지만, 문자열은 널 종단 문자라는 독특한 특징을 가지고 있다.
널 종단 문자
여러개의 문자열이 메모리상에 놓이게 되면 컴퓨터는 어떻게 각각의 문자열 변수를 구분할까?
바로 이러한 구분을 위해 메모리상에서 사용되는 것이 널 종단 문자이다.
s[3]에 쓰여있는 내용이 바로 널 종단 문자로 컴퓨터는 이것을 통해 하나의 문자열이 끝났음을 알 수 있게 된다.
여러개의 문자열 처리
여러 개의 문자열이 입력된다면, 컴퓨터는 어떻게 처리할까?
정답은 2차원 배열을 떠올리면 된다.
예를 들어 name이라는 문자열 배열이 있다면
name안에 각각의 이름들은 순서대로 첫번째 차원의 배열에 들어가게 되고, 그 이름의 각각의 글자들이 두번째 차원의 배열에 들어가게 된다.
문자열 사용시 주의
문자열은 내가 생각하는 문자의 길이보다 최소한 1을 더한 크기 만큼의 메모리를 미리 할당하여야 한다.
그 이유는 당연히 널 종단문자 때문이다.
또한 strlen()의 경우 널 종단문자를 제외하므로 strlen을 통해 불러온 길이는 +1을 하여 생각하지 않고 실제 문자열의 길이로 여기면 된다.
문자열 탐색법
우리가 앞에서 나온 아스키코드를 활용한 탐색법은 다른 언어와 유사하다.
#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");
}
그러나, c와 c++에는 문자열에 대한 편리 기능을 제공하는 몇개의 라이브러리가 있어서 이것을 활용하면 보다 코드를 간결하게 만들 수 있다.
라이브러리 활용
#include <stdio.h>
#include <ctype.h>
int main() {
char str[] = "Hello, World!";
// 문자열의 모든 문자를 대문자로 변환
for (int i = 0; str[i] != '\0'; i++) {
str[i] = toupper(str[i]);
}
printf("Uppercase string: %s\n", str); // 출력: Uppercase string: HELLO, WORLD!
// 문자열의 모든 문자를 소문자로 변환
for (int i = 0; str[i] != '\0'; i++) {
str[i] = tolower(str[i]);
}
printf("Lowercase string: %s\n", str); // 출력: Lowercase string: hello, world!
return 0;
}
위 코드의 for문에서 !=널 종단문자
를 붙이는 이유는 str이 끝나지 않았다면 알파벳의 변경을 진행하기 위해서이다.
만약 숫자 등이 섞여있는 경우 str[i]가 문자인지 아닌지를 먼저 확인 후에 저 작업을 똑같이 진행하면 된다.
string.h
string.h 헤더에서 사람들이 통상적으로 자주 활용하는 것은 strcpy, strcat, strcmp, strchr, strlen
정도인 것 같다.
strlen은 이미 위에서 알아보았고, strcpy는 배열 복사(나는 자주 사용하지 않음)기능을 한다.
strcat은 문자열을 이어붙이는 역할을 하는데 이 역시 c++에서는 문자열에도 덧셈을 붙이는 방식이 있기 때문에 나는 자주 활용하지 않는다.
strcmp의 경우 경고창이나 사용자의 입력을 일괄적으로 관리할 때에(대소문자에 구애받지 않기 위해)사용한 경험이 있으며, strchr의 경우 나는 strstr을 통해 주소값으로 찾아오는 방식을 보다 선호하는 편이다.
ctype.h
위의 헤더보다는 개인적으로 자주 사용하는 기능들이 많다.
isdigit()나 isaplha()와 같은 내장 함수들은 알고리즘 문제를 풀 때에도 정말 활용도가 높은 편이므로 외워두는 편이 좋다.
또한 이 외에도 여러 문자들의 타입을 검사하고 문자를 변환하는 함수가 위 헤더파일 내에 들어있다.
댓글남기기