|
|
[28 연습문제]
// [연습문제]
// 1) [제목, 저자명, 페이지수] 를 저장하는 구조체의 배열을 선언하여 3개를 사용자에게 입력받아 출력하는 프로그램을 작성하시오
// main.c
#include "mylib.h"
int main(void) {
Book books[3];
get_data(books, 3);
print_data(books, 3);
return 0;
}
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H
typedef struct {
char name[20];
char writer[10];
int page;
}Book;
void print_data(Book* books, int len);
void get_data(Book* books, int len);
#endif
// mylib.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include "mylib.h"
void print_data(Book* books, int len) {
for (int i = 0; i < len; i++) {
printf("book %d\n", i + 1);
printf("저자: %s\n", books[i].name);
printf("제목: %s\n", books[i].writer);
printf("페이지 수 %d\n", books[i].page);
}
}
void get_data(Book* books, int len) {
printf("도서 정보 입력\n");
for (int i = 0; i < len; i++) {
printf("저자:");
scanf("%s", books[i].name);
printf("제목:");
scanf("%s", books[i].writer);
printf("페이지 수:");
scanf("%d", &books[i].page);
}
}
// 2) 예제 1의 코드를 배열이 아닌 포인터로 선언하여 동적 할당으로 구현하시오.
// main.c
#include "mylib.h"
#include <stdlib.h>
int main(void) {
Book* books;
get_data(&books, 3);
print_data(books, 3);
free(books);
return 0;
}
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H
typedef struct {
char writer[10];
char name[20];
int page;
}Book;
void print_data(Book* books, int len);
void get_data(Book** books, int len);
#endif
// mylib.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include <stdlib.h>
#include "mylib.h"
void print_data(Book* books, int len) {
for (int i = 0; i < len; i++) {
printf("book %d\n", i + 1);
printf("저자: %s\n", books[i].writer);
printf("제목: %s\n", books[i].name);
printf("페이지 수 %d\n", books[i].page);
}
}
void get_data(Book** books, int len) {
*books = malloc(sizeof(Book) * len);
if (*books == NULL) {
printf("메모리 할당 실패\n");
return;
}
printf("도서 정보 입력\n");
for (int i = 0; i < len; i++) {
printf("저자: ");
scanf(" %s", (*books)[i].writer);
printf("제목: ");
scanf(" %s", (*books)[i].name);
printf("페이지 수: ");
scanf("%d", &(*books)[i].page);
}
}
// 3) 복소수를 나타내는 구조체를 정의하고 덧셈과 곱셈을 위한 함수를 정의하시오.
// main.c
#include "mylib.h"
int main(void) {
complex_num complex[2];
get_data(complex, 2);
comp_sum(complex, 2);
comp_mul(complex, 2);
return 0;
}
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H
typedef struct {
double r, i;
}complex_num;
void comp_sum(complex_num* comp, int len);
void comp_mul(complex_num* comp, int len);
void get_data(complex_num* comp, int len);
#endif
// mylib.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include "mylib.h"
void get_data(complex_num* comp, int len) {
for (int i = 0; i < len; i++) {
printf("복소수 입력[실수 허수]:");
scanf(" %lf %lf", &comp[i].r, &comp[i].i);
}
}
void comp_sum(complex_num* comp, int len) {
complex_num res = { 0, 0 };
for (int i = 0; i < len; i++) {
res.r += comp[i].r;
res.i += comp[i].i;
}
printf("합의 결과: 실수: %lf, 허수: %lf\n", res.r, res.i);
}
void comp_mul(complex_num* comp, int len) {
complex_num res = comp[0];
for (int i = 1; i < len; i++) {
double real = res.r * comp[i].r - res.i * comp[i].i;
double imag = res.r * comp[i].i + res.i * comp[i].r;
res.r = real;
res.i = imag;
}
printf("곱의 결과: 실수: %lf, 허수: %lf\n", res.r, res.i);
}
// 4) 문자열을 저장하고 있는 파일을 열어 a와 p로 시작하는 단어의 수를 세어서 출력하는 프로그램을 작성하시오.
// main.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include "mylib.h"
int main(void) {
char filename[256];
printf("파일 이름 입력: ");
scanf("%255s", filename);
int a_count = count_words(filename, 'a');
int p_count = count_words(filename, 'p');
if (a_count == -1 || p_count == -1) {
printf("파일 열기 실패\n");
return 1;
}
printf("a로 시작하는 단어 수: %d\n", a_count);
printf("p로 시작하는 단어 수: %d\n", p_count);
return 0;
}
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H
#include <stdbool.h>
int count_words(const char* filename, char initial);
#endif
// mylib.c
#include "mylib.h"
#include <stdio.h>
#include <ctype.h>
int count_words(const char* filename, char initial) {
FILE* fp = fopen(filename, "r");
if (!fp) return -1;
int count = 0;
int in_word = 0;
char c;
char target = tolower(initial);
while ((c = fgetc(fp)) != EOF) {
if (c == ' ' || c == '\n' || c == '\t') {
in_word = 0;
}
else {
if (!in_word) {
if (tolower(c) == target) count++;
in_word = 1;
}
}
}
fclose(fp);
return count;
}
// 5) 두 개의 텍스트 파일이 같은지 다른지를 확인하는 프로그램을 작성하시오. 이떄 문자에는 공백문자 또한 포함한다.
// main.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include "mylib.h"
int main(void) {
char file1[256];
char file2[256];
printf("첫 번째 파일명: ");
scanf("%255s", file1);
printf("두 번째 파일명: ");
scanf("%255s", file2);
if (compare_files(file1, file2))
printf("두 파일은 동일합니다.\n");
else
printf("두 파일은 다릅니다.\n");
return 0;
}
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H
#include <stdio.h>
#include <stdbool.h>
bool compare_files(const char* file1, const char* file2);
#endif
// mylib.c
#include "mylib.h"
bool compare_files(const char* file1, const char* file2) {
FILE* f1 = fopen(file1, "r"), * f2 = fopen(file2, "r");
if (!f1 || !f2) {
if (f1) fclose(f1);
if (f2) fclose(f2);
return false;
}
int c1, c2;
do {
c1 = fgetc(f1);
c2 = fgetc(f2);
if (c1 != c2) {
fclose(f1); fclose(f2);
return false;
}
} while (c1 != EOF && c2 != EOF);
fclose(f1); fclose(f2);
return true;
}
// 6) 전화번호 관리 프로그램을 작성하시오. 이때 프로그램은 입력, 삭제, 검색, 전체출력 과 같은 기능을 제공해야 한다.
// main.c
#include "mylib.h"
#include <stdio.h>
int main(void) {
Phone_num** phone_num = NULL;
int len = 0;
commend com = MENU;
Action actions[] = {
NULL, wrap_insert, del, search, printall, NULL
};
while (com != EXIT) {
if (com == MENU) {
menu(&com);
continue;
}
execute(com, phone_num, &len, actions);
menu(&com);
}
return 0;
}
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H
typedef struct {
char name[10];
char num[10];
}Phone_num;
typedef enum{
MENU, INSERT, DEL, SEARCH, PRINTALL, EXIT
}commend;
typedef void (*Action)(Phone_num**, int*);
void execute(commend com, Phone_num** nums, int* len, Action actions[]);
void menu(commend* com);
void insert(Phone_num*** nums, int* len);
void wrap_insert(Phone_num** nums, int* len);
void del(Phone_num** nums, int* len);
void search(Phone_num** nums, int* len);
void printall(Phone_num** nums, int* len);
#endif
// mylib.c
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mylib.h"
void menu(commend* com) {
printf("\n1. insert\n");
printf("2. delete\n");
printf("3. search\n");
printf("4. print all\n");
printf("5. exit\n");
printf("choose the item: ");
scanf(" %d", com);
}
void insert(Phone_num*** nums, int* len) {
Phone_num** temp = realloc(*nums, (*len + 1) * sizeof(Phone_num*));
if (!temp) return;
*nums = temp;
(*nums)[*len] = malloc(sizeof(Phone_num));
if (!(*nums)[*len]) return;
printf("[ insert ]\n");
printf("input name: ");
scanf(" %s", (*nums)[*len]->name);
printf("input Tel number: ");
scanf(" %s", (*nums)[*len]->num);
(*len)++;
}
void del(Phone_num** nums, int* len) {
if (*len == 0) {
printf("삭제할 데이터가 없습니다.\n");
return;
}
printall(nums, len);
int choice;
printf("삭제할 번호를 입력하세요: ");
scanf("%d", &choice);
if (choice < 1 || choice > *len) {
printf("잘못된 번호입니다.\n");
return;
}
free(nums[--choice]);
if (choice != *len - 1) {
nums[choice] = nums[*len - 1];
}
(*len)--;
printf("삭제 완료.\n");
}
void printall(Phone_num** nums, int* len) {
printf("[ print all data ]\n");
for (int i = 0; i < *len; i++) {
printf("%d. name: %s\tTel: %s\n",i+1, nums[i]->name, nums[i]->num);
}
}
void search(Phone_num** nums, int* len) {
char key[20];
printf("검색할 이름 또는 전화번호를 입력하세요: ");
scanf("%19s", key);
int found = 0;
if (key[0] >= '0' && key[0] <= '9') {
for (int i = 0; i < *len; i++) {
if (strstr(nums[i]->num, key) != NULL) {
printf("%d. name: %s\tTel: %s\n",
i + 1, nums[i]->name, nums[i]->num);
found = 1;
}
}
}
else {
for (int i = 0; i < *len; i++) {
if (strstr(nums[i]->name, key) != NULL) {
printf("%d. name: %s\tTel: %s\n",
i + 1, nums[i]->name, nums[i]->num);
found = 1;
}
}
}
if (!found) {
printf("검색 결과가 없습니다.\n");
}
}
void wrap_insert(Phone_num** nums, int* len) {
insert(&nums, len);
}
void execute(commend com, Phone_num** nums, int* len, Action actions[]) {
if (actions[com] != NULL) {
actions[com](nums, len);
}
}
|
|

첫댓글 6번에서 이중포인터를 사용하는 이유를 설명하시오.
strstr 함수의 기능을 설명하시오.
메인함수 외부에서 메인함수에 선언된 변수를 변경해야 하기 때문, 또한 메인함수에서 이중 포인터 구조체로 선언함으로써 구조체변수의 갯수를 조정하고, 각 요소(구조체변수)를 독립적으로 할당, 해제할 수 있음.
strstr() 함수는 첫 번째 인자 문자열에서 두 번째 인자 문자열이 존재하는지를 검사하여, 존재하지 않으면 널 포인터를 반환하고, 존재하면 첫 번째 인자 문자열 내에서 두 번째 인자 문자열이 시작되는 위치의 주소를 반환함.