ex250602 쪽지 시험 - Hwanghyewon06/c- GitHub Wiki
//#pragma warning(disable:4996) // (Visual Studio) 보안 경고(C4996) 무시 설정
//#include <stdio.h> // 표준 입출력 함수 사용 (printf, gets_s 등)
//#include <string.h> // 문자열 관련 함수 사용 (strcmp, strcpy 등)
//#include <stdlib.h> // 동적 메모리 할당 함수 사용 (malloc, free 등)
int main()
{
char* sarr[1000] = { 0 }; // 문자열을 저장할 포인터 배열 선언 및 초기화
int count = 0; // 문자열 입력 개수를 세기 위한 변수
while (1) // 무한 루프 (사용자가 "exit" 입력 시 종료)
{
char buf[1000]; // 문자열 입력을 저장할 임시 배열
printf("문자열 입력:"); // 사용자에게 입력 요청 메시지 출력
gets_s(buf, 1000); // 사용자로부터 문자열 입력 받기 (최대 999자 + 널 문자)
if (strcmp("exit", buf) == 0) // 입력이 "exit"와 같으면
break; // 루프 종료
printf("string : %s\n", buf); // 입력된 문자열을 출력
char* s = (char*)malloc(strlen(buf) + 1); // 입력된 문자열 길이 + 1만큼 동적 메모리 할당
strcpy(s, buf); // 입력된 문자열을 동적 메모리 공간에 복사
sarr[count++] = s; // 복사된 문자열 주소를 배열에 저장하고 count 증가
}
for (int i = 0; i < count; ++i) // 저장된 문자열 모두 출력
printf("[%d] : %s\n", i, sarr[i]); // 인덱스와 함께 문자열 출력
for (int i = 0; i < count; ++i) // 메모리 해제를 위한 반복문
free(sarr[0]); // 문자열 저장용으로 할당한 메모리 해제
}
좋습니다! 주신 코드와 학습 포인트를 기반으로, 쪽지시험용 문제를 출제해 드리겠습니다. 난이도는 초급~중급 수준으로, 메모리 동적 할당, 문자열 처리, 반복문 구조 등 핵심 개념을 점검할 수 있도록 구성했습니다.
다음 코드에서 문자열을 입력받기 위한 함수로 gets()
대신 fgets()
를 사용하는 이유로 적절한 것은?
A. fgets()
는 컴파일 속도가 빠르기 때문이다.
B. fgets()
는 줄바꿈 문자 없이 입력을 받기 때문이다.
C. gets()
는 버퍼 오버플로우 위험이 있어 보안상 안전하지 않기 때문이다.
D. gets()
는 C언어 표준 함수가 아니기 때문이다.
fgets()
를 사용해 문자열을 입력받을 때, 문자열 끝에 자동으로 포함되는 문자를 제거하기 위해 사용하는 C 함수는 무엇인가요?
다음 코드의 잘못된 부분을 찾아 고치세요.
for (int i = 0; i < count; ++i)
free(sarr[0]);
다음 조건에 따라 동작하는 프로그램을 간단히 설명하시오.
- 문자열을 반복적으로 입력받는다.
- 입력된 문자열은 힙에 저장된다.
- “exit”을 입력하면 입력을 중단하고, 지금까지 입력한 문자열을 모두 출력한 후 메모리를 해제한다.
사용자로부터 문자열을 여러 개 입력받아 배열에 저장하고, “exit”이 입력되면 저장된 모든 문자열을 역순으로 출력한 후 메모리를 해제하는 프로그램을 작성하시오. (fgets
사용, 최대 100개 입력)
필요하다면 정답도 함께 제공해드릴 수 있습니다! 좋습니다! 아래는 앞서 출제한 쪽지시험 5문제의 정답과 해설입니다. 이해 중심으로 설명을 덧붙였습니다.
문제: 다음 코드에서 문자열을 입력받기 위한 함수로 gets()
대신 fgets()
를 사용하는 이유로 적절한 것은?
정답: C. gets()
는 버퍼 오버플로우 위험이 있어 보안상 안전하지 않기 때문이다.
해설:
gets()
는 입력 길이에 제한이 없어 입력이 버퍼를 넘으면 버퍼 오버플로우가 발생할 수 있습니다. 이는 보안상 치명적인 취약점입니다. 반면 fgets()
는 최대 입력 길이를 지정할 수 있어 안전합니다. C11 표준에서도 gets()
는 완전히 제거되었습니다.
문제: fgets()
를 사용해 문자열을 입력받을 때, 문자열 끝에 자동으로 포함되는 문자를 제거하기 위해 사용하는 C 함수는 무엇인가요?
정답: strcspn
해설:
fgets()
는 문자열 끝에 \n
개행 문자를 포함시킵니다. 이를 제거하려면 다음과 같이 strcspn()
함수를 사용합니다:
buf[strcspn(buf, "\n")] = '\0';
이 코드는 buf
에서 \n
이 처음 나오는 위치에 널 문자를 삽입해 개행 문자를 제거합니다.
문제: 다음 코드의 잘못된 부분을 찾아 고치세요.
for (int i = 0; i < count; ++i)
free(sarr[0]);
정답:
for (int i = 0; i < count; ++i)
free(sarr[i]);
해설:
free(sarr[0])
는 같은 메모리 주소를 count
번 해제하므로 오류입니다. 각 메모리를 해제하려면 배열의 각 요소를 하나씩 free(sarr[i])
해야 합니다.
문제: 다음 조건에 따라 동작하는 프로그램을 간단히 설명하시오.
- 문자열을 반복적으로 입력받는다.
- 입력된 문자열은 힙에 저장된다.
- “exit”을 입력하면 입력을 중단하고, 지금까지 입력한 문자열을 모두 출력한 후 메모리를 해제한다.
예시 답안:
이 프로그램은 사용자가 입력한 문자열을 동적으로 할당(malloc
)하여 배열에 저장합니다. “exit”을 입력할 때까지 입력을 반복하며, 종료 시 입력된 문자열을 차례대로 출력하고, 할당된 메모리를 모두 해제합니다. 이는 동적 메모리 할당과 문자열 처리, 그리고 메모리 누수 방지를 함께 학습하는 예제입니다.
문제: 사용자가 문자열을 여러 개 입력하면 배열에 저장하고, “exit”이 입력되면 저장된 모든 문자열을 역순으로 출력한 후 메모리를 해제하는 프로그램을 작성하시오.
조건: fgets()
사용, 최대 100개 문자열 입력 가능.
정답 예시:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char* sarr[100] = { 0 };
int count = 0;
while (count < 100) {
char buf[1000];
printf("문자열 입력: ");
if (fgets(buf, sizeof(buf), stdin) == NULL)
break;
buf[strcspn(buf, "\n")] = '\0';
if (strcmp(buf, "exit") == 0)
break;
char* s = (char*)malloc(strlen(buf) + 1);
if (!s) {
printf("메모리 할당 실패\n");
break;
}
strcpy(s, buf);
sarr[count++] = s;
}
// 역순 출력
for (int i = count - 1; i >= 0; --i)
printf("[%d] : %s\n", i, sarr[i]);
// 메모리 해제
for (int i = 0; i < count; ++i)
free(sarr[i]);
return 0;
}
해설:
-
fgets()
로 입력 받음 → 개행 제거 -
strcmp()
로 “exit” 확인 -
malloc()
으로 복사 -
count - 1
부터 역순으로 출력 - 모든 동적 메모리를 해제
이 문제 세트는 교수님이 실제 쪽지시험에 내기 좋은 형태입니다. 필요하면 객관식 선택지 바꾸기, 또는 객관식 정답 랜덤화도 해드릴 수 있어요.
함수 이름 | 한줄 요약 설명 |
---|---|
strcmp(a, b) | 문자열 a와 b를 비교하여 같으면 0을 반환함 |
strcpy(dest, src) | 문자열 src를 dest에 복사함 |
strlen(s) | 문자열 s의 길이를 반환함 ('\0' 제외한 문자 수) |
함수 이름 | 한줄 요약 설명 |
---|---|
malloc(size) | size 바이트만큼 메모리를 동적으로 할당함 |
free(ptr) | 동적으로 할당된 메모리 ptr을 해제함 |