2-1, 2-3 수정
2-1 주소록
- address 크기가 temp 크기보다 크기 때문에 temp 사이즈를 수정중..
- 메모리 낭비 안하기..
- 임시 공간 temp[50]에 이름을 입력받음
- 한글 4자까지 입력 가능하지만 공백도 입력받기 때문에 char name[13]보다는 temp가 커야함
- 여기서 만약 입력받은 문자열이 temp[50]을 넘어간다면? 넘지 않는다면?
void SetInfo(Info* info)
{
char temp[200];
int j=0;
printf("이름: ");
getchar();
fflush(stdin);
gets(temp);
for (int i=0; i<sizeof(temp); i++)
if (temp[i]!=' '){
temp[j] = temp[i];
j++;
}
snprintf(info->name, 13, "%s", temp);
j=0;
//<--getchar로 받는 방법-->
//while ((ch = getchar()) != '\n')
// if (ch != ' ')
// temp[i++] = ch;
//temp[i] = '\0';
//snprintf(info->name, 13, "%s", temp);
printf("전화번호: ");
fflush(stdin);
gets(temp);
snprintf(info->phone, 14, "%s", temp);
printf("주소: ");
fflush(stdin);
gets(temp);
for (int i=0; i<sizeof(temp)-1; i++)
if (temp[i]==' ' && temp[i+1]==' ')
continue;
else{
temp[j] = temp[i];
j++;
}
snprintf(info->address, 151, "%s", temp);
}
2-3 문자열
my_strcpy
- my_strcpy 함수는 if문으로 수정했습니다.
- my_strcpy 함수에서 dest_buf_size 값과 비교되는 대상 값이 같을 때 temp 값을 dest_buf_size-1로 적용했습니다.
int my_strcpy(char* dest, size_t dest_buf_size, const char* src, size_t src_buf_size)
{
size_t temp = 0;
if (strlen(src) < src_buf_size) {
if (dest_buf_size <= strlen(src))
temp = dest_buf_size - 1;
else
temp = strlen(src);
}
else {
if (dest_buf_size <= src_buf_size)
temp = dest_buf_size - 1;
else
temp = src_buf_size;
}
for (int i=0; i<temp; i++)
dest[i] = src[i];
dest[temp] = '\0';
return 0;
}
my_strcat, mystrstr, mystrtok
- my_strcat 함수 수정
- my_strcat, my_strstr, my_strtok 함수 설명
char* my_strcat(char* str, const char* add)
{
char* c;
c = str;
while (*str!='\0'){
//*c = *str; //불필요함
c++;
str++;
}
while (*add!='\0'){
*c = *add;
c++;
add++;
}
*c = '\0';
return c;
}
char* my_strstr(const char* str, const char* find)
{
char* c = NULL;
if (*find == '\0') //전달받은 인자의 값이 NULL이면
return (char*)str; //str 문자열 그대로 반환함
while (*str != '\0'){ //str 문자 값이 NULL이 되면 반복문 중지
if (c != NULL && *find == '\0') //find 문자열을 전부 탐색했으면 반복문 탈출
break;
if (c != NULL && *str != *find) //find가 포함된줄 알다가, 똑같지 않은 상태인거 알고
c = NULL; //c를 다시 비워줌
if (c == NULL && *str == *find) //c가 비어있는 상태에서 find의 첫번째 값을 찾았다면,
c = (char*)str; //find의 첫번째 값의 포인터를 c에 대입함
if (c != NULL && *str == *find) //위 if문에서 바로 연결되어서, find 포인터 1증가
find++; //(find의 두번째 값을 검색하기 시작함)
str++; //str 포인터 1증가 (find를 찾지 못하면 계속 str++만 반복함)
}
if (c != NULL)
return c; //c가 NULL이 아니면, c를 리턴함
else
return NULL; //str에 find가 나타나지 않았으니 NULL을 리턴함
}
char* my_strtok(char* str, const char* delim)
{
static char* s = NULL; //str 문자열 계속 저장하기 위해 정적변수 s를 선언함
char* d = NULL; //while문 반복을 위해 임시공간 d를 선언함
if (str != NULL) //처음 전달된 str 문자열 s에 대입함
s = str;
else //구분자를 찾으면 그 구분자를 '\0'로 변환하기 때문에
//처음에만 문자열 전체를 넣어주고, 그 다음부터 '\0'부터 찾음
str = s; //아래 while 반복문에서 s가 가리키는 위치는 잘린문자열+'\0' 그 이후로,
//정적변수인 s는 함수를 벗어나도 유지됨 - 그대로 str에 대입함
if (*s == '\0') //더이상 자를 문자열이 없으면 NULL을 리턴함
return NULL;
while (*s != '\0) {
d = (char*)delim; //d에 구분자를 대입함
while (*d != '\0') {
if (*s == *d) { //문자열 중 구분자를 찾으면
*s = '\0'; //그 구분자를 '\0'로 바꾸어줌
s++; //다음 구분될 문자열 찾기 위해 s 포인터 1 증가
return str; //'\0'을 만날때까지의 (자른) 문자열을 리턴함
}
d++;
}
s++;
}
return str; //구분자 없이 남은 마지막 문자열은 위 while문에서 구분자를 찾지 못하기 때문에
//따로 문자열을 리턴해야함
}
수강신청.c
<-- 수정 중 입니다. -->
5. 수강신청 프로그램에서 CountCheck 함수와 에러 리턴값을 수정했습니다.
6. NameCheck 함수에서 strstr로 과목명을 검색하는건 잘못된 방식이어서 strcmp로 수정했습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MIN_ID_NUM=1, MAX_ID_NUM=100, MAX_INFO_NUM=5 };
typedef struct Info {
int id;
char subjects[116];
} Info;
/////////////////////////////////////////////////////// 수정해야할 위치
const char* Name_Subjects =
"컴퓨터개론, 이산수학, C언어, JAVA초급,
리눅스구조, 자료구조, 컴파일러, 네트워크개론"; //115
///////////////////////////////////////////////////////
int IDRangeCheck(Info* info)
{
if (info->id < MIN_ID_NUM || info->id > MAX_ID_NUM){
puts("ID의 범위는 1부터 100입니다.");
return -1;
}
return 0;
}
int CountCheck(int* num)
{
if (*num >= MAX_INFO_NUM){
puts("수강 신청 정보가 5개를 초과하였습니다.");
return -1;
}
return 0;
}
/////////////////////////////////////////////////////// 수정해야할 위치
int NameCheck(char* str)
{
if (strstr(Name_Subjects, str)==NULL){
puts("존재하지 않은 과목명을 입력하였습니다.");
return -1;
}
return 0;
}'
///////////////////////////////////////////////////////
int Menu()
{
int select;
do{
puts("======================");
puts("1) 수강 신청 정보 입력");
puts("2) 수강 신청 정보 출력");
puts("3) 종료");
printf("Select ==> ");
scanf("%d", &select);
} while (select!=1 && select!=2 && select!=3);
return select;
}
int SetInfo(Info* info)
{
char copystr[116];
int j=0;
copystr[0] = '\0';
info->subjects[0] = '\0';
printf("ID: ");
scanf("%d", &info->id);
if (IDRangeCheck(info)) //ID범위 체크
return -1;
printf("수강 신청 과목: ");
getchar();
fflush(stdin);
gets(copystr);
for (int i=0; i<sizeof(copystr); i++) //공백 제거
if (copystr[i]!=' ')
copystr[j++]=copystr[i];
char* temp = strtok(copystr, ","); //콤마 분할
while (temp!=NULL){
if (NameCheck(temp)) //과목명 체크
return -1;
strcat(info->subjects, temp); //과목명 이어붙이기
temp = strtok(NULL, ",");
if (temp!=NULL)
strcat(info->subjects, ", "); //마지막 과목 빼고 ", " 덧붙이기
}
return 0;
}
void GetInfo(Info* info)
{
printf("ID: %d, 수강신청 과목: ", info->id);
puts(info->subjects);
}
int main()
{
Info data[MAX_INFO_NUM];
int count = 0;
while(1)
{
switch(Menu())
{
case 1:
{
if (CountCheck(&count))
break;
if (!SetInfo(&data[count]))
count++;
}
break;
case 2:
{
if (!count)
puts("등록된 정보가 없습니다.");
for (int i=0; i<count; i++)
GetInfo(&data[i]);
}
break;
case 3:
{
puts("프로그램을 종료합니다.");
return 0;
}
}
}
return 0;
}
Author And Source
이 문제에 관하여(2-1, 2-3 수정), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@doheeklm/2-1-2-3-수정저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)