문자열을 복사하기 위해 아래 코드를 실행하면 어떻게 될까요?
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
int main(void)
{
string s = get_string("s: ");
string t = s;
t[0] = toupper(t[0]);
printf("s: %s\n", s);
printf("t: %s\n", t);
}
사용자에게 입력값을 받아 string s에 저장하고, string t를 s로 정의합니다.
그리고 t의 첫 번째 문자를 toupper 함수를 이용하여 대문자로 바꾼다면 s와 t는 각각 어떻게 출력 될까요?
입력값으로 “emma”를 주게 된다면, 단순한 예상과는 다르게 s와 t 모두 “Emma”라고 출력이 됩니다.
그 이유는 s라는 변수에는 “emma”라는 문자열이 아닌 그 문자열이 있는 메모리의 주소가 저장되기 때문이죠.
string s 는 char *s 와 동일한 의미라는걸 떠올려보면 됩니다.
따라서 t도 s와 동일한 주소를 가리키고 있고, t를 통한 수정은 s에도 그대로 반영이 되게 되는 것입니다.
그렇다면 두 문자열을 실제로 메모리상에서 복사하려면 어떻게 해야 할까요?
아래 코드와 같이 메모리 할당 함수를 사용하면 됩니다
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char *s = get_string("s: ");
char *t = malloc(strlen(s) + 1);
for (int i = 0, n = strlen(s); i < n + 1; i++)
{
t[i] = s[i];
}
t[0] = toupper(t[0]);
printf("s: %s\n", s);
printf("t: %s\n", t);
}
위의 코드와 다른 점은 malloc이라는 함수를 이용해서 t를 정의한다는 거죠.
malloc 이라는 함수는 정해진 크기 만큼 메모리를 할당하는 함수입니다.
즉 s 문자열의 길이에 널 종단 문자(\0)에 해당하는 1을 더한 만큼 메모리를 할당합니다.
그리고 루프를 돌면서 s 문자열 배열에 있는 문자 하나 하나를 t 배열에 복사해주면 됩니다.
이 코드를 컴파일 후 실행시키고 입력값으로 “emma”를 주면 우리가 예상한 대로 s는 “emma”가, t는 “Emma”가 출력되게 됩니다.
성공적으로 복사가 된 것을 확인할 수 있습니다.