C

윤성우의 열혈 C 프로그래밍 도전4

나른한여우 2024. 3. 4. 22:28

도전1

구조체 배열을 이용한 도서 정보 출력

typedef struct {
	char name[50];
	char writer[50];
	int pageSize;
} BOOK;

int main(void) {

	BOOK bookList[3];
	for (int i = 0; i < 3; i++) {
		printf("저자: ");
		gets_s(bookList[i].writer, 50);
		printf("제목: ");
		gets_s(bookList[i].name, 50);
		printf("페이지 수: ");
		scanf_s("%d", &bookList[i].pageSize);
		getchar();
	}

	printf("\n도서 정보 출력\n");
	for (int i = 1; i < 4; i++) {
		printf("book %d\n", i);
		printf("저자: %s\n", bookList[i - 1].writer);
		printf("제목: %s\n", bookList[i - 1].name);
		printf("페이지 수: %d\n", bookList[i - 1].pageSize);
	}


	return 0;
}

 

도전2

도전1에서 구현한 프로그램에 구조체 배열선언이 아니라 구조체 포인터 배열을 선언하고

구조체 변수를 동적으로 할당하는 형태로 프로그램을 재 구현

#include <stdio.h>
#include <stdlib.h>

typedef struct {
	char name[50];
	char writer[50];
	int pageSize;
} BOOK;

int main(void) {

	//도전1과 다르게 구조체 포인터 배열 선언
	BOOK* bookList[3];
    	//구조체 변수를 동적 할당받을 ptr선언
	BOOK* ptr = (BOOK*)malloc(sizeof(BOOK) * 3);
	for (int i = 0; i < 3; i++) {
		printf("저자: ");
		gets_s(ptr[i].writer, 50);
		printf("제목: ");
		gets_s(ptr[i].name, 50);
		printf("페이지 수: ");
		scanf_s("%d", &ptr[i].pageSize);
		getchar();
        	//위에서 선언한 구조체 포인터 배열(bookList)이 동적 할당된 구조체 변수(ptr)의
        	//주소값을 가르키도록 해줌
		bookList[i] = &ptr[i];
	}

	printf("\n도서 정보 출력\n");
	for (int i = 1; i < 4; i++) {
		printf("book %d\n", i);
		printf("저자: %s\n", bookList[i - 1]->writer);
		printf("제목: %s\n", bookList[i - 1]->name);
		printf("페이지 수: %d\n", bookList[i - 1]->pageSize);
	}

	free(ptr);

	return 0;
}

 

내가 생각한 도전1에서 구현한 방법보다 도전 2에서 구현한 방법이 지니는 장점은 

직접 관리할수있는 동적 할당된 메모리내에서 변수를 관리할수있다는 점과

주소정보를 저장할 포인터 배열과 데이터를 저장할 동적 할당된 구조체 변수를 나누어

데이터를 관리를 용이하게 만든것이라고 생각함

(정확한 해답은 보지않았기때문에 틀릴 수 있음..)

 

도전3

복소수를 나타내는 구조체를 정의하고 복소수의 덧셈과 곱셈을 위한 함수를 각각 정의하자.

이를 기반으로 프로그램 사용자로부터 두 개의 복소수 정보를 입력 받아 두 복소수의 덧셈과 곱셈의 결과를 출력

#include <stdio.h>

typedef struct {
	double aNum;
	double iNum;
}CNUM;

CNUM SumCNUM(CNUM cnum1, CNUM cnum2) {
	CNUM result;
	result.aNum = cnum1.aNum + cnum2.aNum;
	result.iNum = cnum1.iNum + cnum2.iNum;

	return result;
}

CNUM MulCNUM(CNUM cnum1, CNUM cnum2) {
	CNUM result;
	result.aNum = (cnum1.aNum * cnum2.aNum) - (cnum1.iNum * cnum2.iNum);
	result.iNum = (cnum1.iNum * cnum2.aNum) + (cnum1.aNum * cnum2.iNum);

	return result;
}

int main(void) {

	CNUM cnum1, cnum2;
	CNUM sum, mul;
	printf("복소수 입력1[실수 허수]: ");
	scanf_s("%lf %lf", &cnum1.aNum, &cnum1.iNum);
	printf("복소수 입력1[실수 허수]: ");
	scanf_s("%lf %lf", &cnum2.aNum, &cnum2.iNum);

	sum = SumCNUM(cnum1, cnum2);
	mul = MulCNUM(cnum1, cnum2);

	printf("합의 결과] 실수: %g, 허수: %g\n", sum.aNum, sum.iNum);
	printf("곱의 결과] 실수: %g, 허수: %g", mul.aNum, mul.iNum);

	return 0;
}

 

도전4

문자열을 저장하고 있는 파일을 열어서 A와 P로 시작하는 단어의 수를 세어서 출력하는 프로그램을 작성해 보자.

단 모든 단어는 공백문자(스페이스바, \t, \n)에 의해서 구분된다고 가정한다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(int argc, char* argv[]) {
	char word[20];
	int Anum = 0, Pnum = 0;

	FILE* fp = fopen(argv[1], "rt");
	if (fp == NULL) {
		puts("파일오픈 실패");
		return -1;
	}

	int ret;
	while (1) {
		ret = fscanf_s(fp, "%s", word, 20);
		if (ret == EOF)
			break;
		if (word[0] == 'A')
			Anum++;
		if (word[0] == 'P')
			Pnum++;
	}

	printf("A로 시작하는 단어의 수: %d\n", Anum);
	printf("P로 시작하는 단어의 수: %d", Pnum);

	fclose(fp);

	return 0;
}

 

도전5

두 개의 텍스트 파일이 같은지 다른지를 확인하는 프로그램을 작성해 보자. 단순히 공백문자 하나가 차이를 보여도 

두 텍스트 파일은 다른 것으로 판별이 나야 한다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {

	char str1[100];
	char str2[100];
	char flag = 'Y';
	FILE* fp = fopen(argv[1], "rt");
	if (fp == NULL) {
		puts("파일오픈 실패");
		return -1;
	}

	FILE* fp2 = fopen(argv[2], "rt");
	if (fp == NULL) {
		puts("파일오픈 실패");
		return -1;
	}

	while (fgets(str1, sizeof(str1), fp) != NULL && fgets(str2, sizeof(str2), fp2) != NULL) {
		if (strcmp(str1, str2) != 0) {
			flag = 'N';
			break;
		}
	}

	if(flag=='N')
		printf("두 개의 파일은 일치하지 않습니다.");
	else
		printf("두 개의 파일은 완전히 일치 합니다.");

	fclose(fp);
	fclose(fp2);

	return 0;
}

 

도전6, 7

전화번호 관리 프로그램을 작성 해보자.

-입력 : 이름과 전화번호를 입력

-삭제 : 이름을 입력하여 해당 이름의 정보 삭제

-검색 : 이름을 입력하여 해당 이름의 정보 출력

-전체출력 : 저장된 모든 이름과 전화번호 정보를 출력

+ 파일저장 및 불러오기

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
// 1. 입력 2. 삭제. 3. 검색 4. 전체출력 5. 종료

typedef struct {
	char name[20];
	char number[20];
} LIST;

int main(void) {
	
	int switchNum;
	int i = 0, fileIndex = 0;
	char exitCase = 'N';
	LIST AllList[100];

	FILE* ulf = fopen("userList.txt", "rt");
	if (ulf != NULL) {
		while (1)
		{
			fscanf(ulf, "%s %s", AllList[fileIndex].name, AllList[fileIndex].number);
			if (feof(ulf) != 0)
				break;
			fileIndex++;
		}

		i = fileIndex;

		fclose(ulf);
	}

	while (exitCase == 'N') {
		printf("***** MENU *****\n");
		printf("1. Insert\n");
		printf("2. Delete\n");
		printf("3. Search\n");
		printf("4. Print All\n");
		printf("5. Exit\n");
		printf("Choose the item: ");
		scanf_s("%d", &switchNum);
		getchar();

		switch (switchNum) {
			case 1:
				//입력
				printf("[ INSERT ]\n");
				printf("Input Name: ");
				gets_s(AllList[i].name, 20);
				printf("Input Tel Number: ");
				gets_s(AllList[i].number, 20);
				i++;
				printf("		Data Inserted		\n");
				break;
			case 2:
				//삭제
				printf("[ DELETE ]\n");
				char deleteName[20];
				char deleteFlag = 'N';
				printf("Delete Name: ");
				gets_s(deleteName, 20);
				for (int j = 0; j < i; j++) {
					if (!strcmp(deleteName, AllList[j].name)) {
						deleteFlag = 'Y';
						for (int x = j; x < i; x++) {
							strcpy(AllList[x].name, AllList[x + 1].name);
							strcpy(AllList[x].number, AllList[x + 1].number);
						}
						i--;
						printf("데이터 삭제 성공!\n");
					}
				}
				if (deleteFlag == 'N')
					printf("해당 데이터가 존재하지않습니다.\n");
				break;
			case 3:
				//검색
				printf("[ PRINT DATA ]\n");
				if (i == 0) {
					printf("입력된 데이터가 없습니다.\n");
					break;
				}
				char searchName[20];
				char searchFlag = 'N';
				printf("Search Name: ");
				gets_s(searchName, 20);
				for (int j = 0; j < i; j++) {
					if (!strcmp(searchName, AllList[j].name)) {
						searchFlag = 'Y';
						printf("Name : %3s	", AllList[j].name);
						printf("Tel Number : %3s\n", AllList[j].number);
					}
				}
				if (searchFlag == 'N')
					printf("해당 데이터가 존재하지않습니다.\n");
				break;
			case 4:
				//전체출력
				printf("[ PRINT ALL DATA ]\n");
				if (i == 0) {
					printf("입력된 데이터가 없습니다.\n");
					break;
				}
				for (int j = 0; j < i; j++) {
					printf("Name : %3s	", AllList[j].name);
					printf("Tel Number : %3s\n", AllList[j].number);
				}
				break;
			case 5:
				//종료
				printf("종료!!");
				exitCase = 'Y';

				FILE* fp = fopen("userList.txt", "wt");
				if (fp == NULL) {
					puts("파일오픈 실패!");
					return -1;
				}

				for (int j = 0; j < i; j++) {
					fprintf(fp, "%s %s\n", AllList[j].name, AllList[j].number);
				}

				fclose(fp);
				break;
		}
		printf("\n");

	}

	return 0;
}