std::string과 스트림 클래스를 사용해서 무제한으로 문자열을 입출력할 수 있는
ANSI C++에 비해서,
C의 scanf()와 char 배열을 사용한 방법은
문자열 길이의 제한이 있을 뿐만 아니라,
제한을 넘어서 입력해도 화면상에 그대로 표시되는 문제점이 있습니다.
C에서 C++ string처럼 무제한으로 입력하려면 다음과 같이
malloc()과 realloc()으로 메모리를 할당/재할당하고,
scanf()대신 getchar()로 한 글자 씩 입력받아 처리하면 됩니다.
(자료실에 올린 Bjarne Stroustrup의 글인 "Learning Standard C++ as a New Language"
에 있는 코드를 약간 수정했습니다.
http://www.borlandforum.com/impboard/impboard.dll?action=read&db=cpp_res&no=17
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
void quit();
void input_str(char** str);
int main()
{
char *name;
printf("Please enter your full name: ");
input_str(&name);
printf("\nHello, %s.\n", name);
free(name); /* release memory */
return 0;
}
void quit() /* write error message and quit */
{
fprintf(stderr, "Memory exhausted.\n");
exit(1);
}
void input_str(char** str) {
#define DEFAULT_LEN 20
int max = DEFAULT_LEN, i = 0, c;
if ((*str = (char*)malloc(max)) == NULL) /* allocate buffer */
quit();
while (1) { /* skip leading whitespace */
int c = getchar();
if (c == EOF) break; /* end of file */
if (!isspace(c)) {
ungetc(c,stdin);
break;
}
}
while (1) {
c = getchar();
if (c == '\n' || c == EOF) { /* at end; add terminating zero */
(*str)[i] = 0;
break;
}
(*str)[i] = c;
if (i == max - 1) { /* buffer full */
max *= 2;
*str = (char*)realloc(*str, max); /* get a new and larger buffer */
if (*str == 0) quit();
}
i++;
}
}
주의1: input_str(char** str)의 이중 포인터 사용에 유의하세요.
주의2: 사용 후에는 반드시 free()로 할당된 메모리를 해제해야 합니다.
strdup() 함수의 사용법과도 비슷하죠.
버그 발생의 원인이 될 수 있는 좋지 않은 구현 방법이지만 어쩔 수 없겠네요.