동적 문자열 빌더
Coddy C 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 61개 중 59번째.
챌린지
쉬움텍스트를 추가할 때마다 자동으로 크기가 늘어나는 동적 문자열 컨테이너인 StringBuilder를 만들어 봅시다. 이것은 이 과정 전반에서 익힌 OOP 패턴과 동적 메모리 관리를 결합한 실용적인 유틸리티입니다.
코드는 세 개의 파일로 구성됩니다:
stringbuilder.h: 세 개의 멤버를 가진StringBuilder구조체를 선언합니다:char*버퍼, 현재 길이를 위한size_t, 그리고 전체 용량을 위한size_t. StringBuilder 생성, 텍스트 추가, 최종 문자열 검색, 메모리 해제를 위한 함수 프로토타입을 선언합니다. 인클루드 가드(Include guards)는 필수입니다.stringbuilder.c: StringBuilder 시스템을 구현합니다:create_stringbuilder— 힙에 StringBuilder를 할당하고, 버퍼를 초기 용량 16바이트로 초기화하며, 길이를 0으로 설정하고, 버퍼가 빈 문자열(null-terminated)로 시작하도록 보장합니다.append— StringBuilder 포인터와 추가할 문자열을 받습니다. 새로 필요한 길이를 계산합니다. 용량을 초과하면 용량을 두 배로 늘리고(필요한 경우 반복적으로),realloc을 사용하여 버퍼를 확장합니다. 그런 다음strcat을 사용하여 새 텍스트를 연결합니다.get_string— 내부 버퍼에 대한 포인터를 반환합니다 (읽기 전용 접근).free_stringbuilder— 버퍼를 먼저 해제한 다음 StringBuilder 구조체 자체를 해제합니다.
main.c: 추가할 문자열의 개수를 나타내는 정수를 읽습니다. 그런 다음fgets를 사용하여 각 문자열을 읽고 StringBuilder에 추가합니다. 모든 문자열이 추가되면get_string을 사용하여 완성된 전체 문자열을 출력합니다. 마지막으로 StringBuilder를 해제합니다.
이 챌린지에서 사용되는 두 가지 핵심 함수:
realloc(ptr, new_size)— 이전에 할당된 메모리 블록의 크기를 조정합니다. 기존 블록에 대한 포인터와 바이트 단위의 새로운 원하는 크기를 인자로 받아, 크기가 조정된(위치가 이동될 수 있는) 블록에 대한 포인터를 반환합니다. 버퍼를 확장해야 할 때append에서 사용하세요:sb->buffer = (char*)realloc(sb->buffer, sb->capacity);fgets(buffer, size, stream)— 입력 스트림에서 텍스트 한 줄을 읽어 문자 배열에 저장하며, 줄바꿈 문자를 만나거나size - 1개의 문자를 읽으면 멈춥니다. 버퍼에 줄바꿈 문자를 유지하므로 수동으로 제거해야 합니다.main.c에서 각 입력 문자열을 읽을 때 사용하세요:fgets(line, sizeof(line), stdin);
마지막 줄바꿈 문자를 제거하려면: 마지막 문자가'\n'인지 확인하고'\0'으로 바꿉니다.
프로그램은 다음을 입력받습니다:
- 추가할 문자열의 개수
- 각 줄에 하나씩 입력되는 문자열들
입력이 3이고, 이어서 Hello, , World인 경우의 예시 출력:
Hello World입력이 4이고, 이어서 C, is, a, great language!인 경우의 예시 출력:
C is a great language!입력이 1이고, 이어서 SingleString인 경우의 예시 출력:
SingleString각 추가 작업 후에 length 필드를 업데이트하는 것을 잊지 마세요. 재할당이 필요한지 확인할 때 널 종료 문자(null terminator)를 고려해야 합니다. 버퍼에는 length + new_text_length + 1 바이트의 공간이 필요합니다. 문자열 길이를 측정하려면 <string.h>의 strlen을 사용하세요. 또한 main.c에서 fgets로 문자열을 읽기 전에 scanf 후에 남은 줄바꿈 문자를 소비하기 위해 getchar()를 호출하세요.
직접 해보기
#include <stdio.h>
#include <stdlib.h>
#include "stringbuilder.h"
int main() {
int n;
scanf("%d", &n);
getchar(); // 숫자 뒤의 개행 문자 소비
// TODO: create_stringbuilder()를 사용하여 StringBuilder 생성
// TODO: n개의 문자열을 읽고 각각을 StringBuilder에 추가
// 힌트: 각 줄을 읽기 위해 fgets 또는 유사한 함수를 사용하세요
// fgets를 사용하는 경우 개행 문자를 처리해야 함을 기억하세요
// TODO: get_string()을 사용하여 완성된 전체 문자열 출력
// TODO: free_stringbuilder()를 사용하여 StringBuilder 해제
return 0;
}