Skip to content

CHAPTER 12

Tony Kim edited this page Oct 21, 2019 · 28 revisions

표준 입출력과 파일 입출력

  • 1번 문제

텍스트 파일의 이름을 입력받아 라인 번호와 함께 내용을 출력하는 프로그램

README.txt

This is text file for input test.
This file contains multiple lines of text.
The program displays the content of file with line number.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> // strlen() 함수
#include <stdlib.h> // exit()함수
#define SIZE  100
int main(void) {
	char text_filename[SIZE];
	char text_contents[SIZE];
	int count = 1; // 라인 번호
	FILE* fp;
	// 파일 이름을 입력받아 읽기 전용으로 파일 불러옴
	printf("파일명? ");
	gets_s(text_filename, SIZE);
	fp = fopen(text_filename, "r");

	// 파일 이름이 일치하지 않으면 Error! 출력 후 종료
	if (fp == NULL) {
		printf("Error!\n");
		exit(1);
	}

	// fgets함수는 개행문자(\n)까지 받는다 그러므로 개행문자를 NUL문자(\0)로 변경
	while (!feof(fp)) {
		fgets(text_contents, SIZE, fp);
		if (text_contents[strlen(text_contents) - 1] == '\n') {
			text_contents[strlen(text_contents) - 1] = '\0';
		}
		printf("%3d: ", count); // 라인 번호 출력
		puts(text_contents); // 텍스트 내용 출력
		count++; // 라인 번호 증가
	}
	fclose(fp);
}
[실행 결과]

파일명? README.txt
  1: This is text file for input test.
  2: This file contains multiple lines of text.
  3: The program displays the content of file with line number.
  • 2번 문제

텍스트 파일의 이름을 입력받아 모든 내용을 소문자로 변환해 출력하는 프로그램

README.txt

This is text file for input test.
This file contains multiple lines of text.
The program displays the content of file with line number.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> //strlen(), _strlwr()함수 
#define SIZE 300
int  main(void) {
	char text_filename[SIZE];
	char text_contents[SIZE];
	FILE* fp;
	printf("파일명? ");
	// 파일 이름을 입력받아 읽기 전용으로 파일 불러옴
	gets_s(text_filename, SIZE);
	fp = fopen(text_filename, "r");
	// 파일 이름이 일치하지 않으면 Error! 출력 후 종료
	if (fp == NULL) {
		printf("Error!\n");
		return 1;
	}
	// fgets함수는 개행문자(\n)까지 받는다 그러므로 개행문자를 NUL(\0)로 변경
	while (!feof(fp)) {
		fgets(text_contents, SIZE, fp);
		if (text_contents[strlen(text_contents) - 1] == '\n') {
			text_contents[strlen(text_contents) - 1] = '\0';
		}
		_strlwr(text_contents); // strlwr함수를 이용해 대문자를 소문자로 변경
		puts(text_contents); // 텍스트 내용 출력
	}
	fclose(fp);
}
[실행 결과]

파일명? README.txt
this is text file for input test.
this file contains multiple lines of text.
the program displays the content of file with line number.
  • 3번 문제

텍스트 파일의 이름을 입력받아 모든 내용을 출력하고 파일 내의 영문자의 갯수를 세서 출력하는 프로그램

README.txt

This is text file for input test.
This file contains multiple lines of text.
The program displays the content of file with line number.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> //strlen()함수
#define SIZE 300
int main(void) {
	char text_filename[SIZE];
	char text_contents[SIZE];
	
	FILE* fp;
	printf("파일명? ");
	// 파일 이름을 입력받아 읽기 전용으로 파일 불러옴
	gets_s(text_filename, SIZE);
	fp = fopen(text_filename, "r");
	// 파일을 찾지 못하면 Error! 출력 후 종료
	if (fp == NULL) {
		printf("Error!\n");
		return 1;
	}
	// 영문자를 비교하고 저장할 배열 선언
	char ABC[21] = { 'A','B','C','D','E','F','G','H','I','L','M','N','O','P','R','S','T','U','W','X','Y' };
	char abc[21] = { 'a','b','c','d','e','f','g','h','i','l','m','n','o','p','r','s','t','u','w','x','y' };
	int ABC_num[21];
	for (int i = 0; i < 21; i++) {
		ABC_num[i] = 0;
	}
	// fgets함수는 개행문자(\n)까지 받는다 그러므로 개행문자를 NUL(\0)로 변경 후 출력
	while (!feof(fp)) {
		fgets(text_contents, SIZE, fp);
		if (text_contents[strlen(text_contents) - 1] == '\n') {
			text_contents[strlen(text_contents) - 1] = '\0';
		}
		puts(text_contents);	
		// 영문자 소문자와 대문자를 비교해 ABC_num에 그 갯수를 저장
		for (int i = 0; i < 21; i++) {
			for (int k = 0; k < SIZE; k++) {
				if ((text_contents[k] == abc[i]) || (text_contents[k] == ABC[i]))
					ABC_num[i] = ABC_num[i] + 1;
			}
		}
	}
	// 저장한 영문자의 갯수를 출력
	for (int i = 0; i < 21; i++) {
		printf("%3c:%2d", ABC[i], ABC_num[i]);
		if ((i % 10 == 0) && (i != 0))
			printf("\n");
	}
	fclose(fp);
}
파일명? README.txt
This is text file for input test.
This file contains multiple lines of text.
The program displays the content of file with line number.
  A: 3  B: 1  C: 2  D: 1  E:13  F: 6  G: 1  H: 5  I:13  L: 8  M: 3
  N: 8  O: 6  P: 4  R: 4  S: 8  T:16  U: 3  W: 1  X: 2  Y: 1
  • 4번 문제

아이디와 비밀번호가 저장된 텍스트 파일을 구조체에 저장해 로그인 프로그램을 구현

Password.txt

admin abc123
pizza beer
coke pepsi
Mac Ms
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> // strcmp()함수
#define SIZE 10
struct Login {
	char ID[SIZE];
	char Password[SIZE];
};
int main(void) {
	struct Login a[4];
	char ID[SIZE];
	char Password[SIZE];
	FILE* fp;
	// 파일을 읽기 전용으로 불러옴
	fp = fopen("password.txt", "r");
	// 텍스트에 저장된 정보를 구조체로 가져옴
	for (int i = 0; i < 4; i++) {
		fscanf(fp, "%s %s", &a[i].ID, &a[i].Password);
	}
	// 파일 닫기
	fclose(fp);
	for (;;) {
		start:
		printf("ID? ");
		scanf("%s", ID);
		// .을 입력하면 프로그램 종료
		if (*ID == '.')
			break;
		for (int i = 0; i < 4; i++) {
			// ID 비교
			if (!strcmp(ID, a[i].ID)) {
				getchar();
				printf("Password? ");
				scanf("%s", Password);
				// Password 비교
				if (!strcmp(Password, a[i].Password)) {
					printf("Login Successful!\n");
					goto start;
				}
				printf("Password Error!\n");
				goto start;
			}
		}
		printf("ID Error!\n");
	}
}
[실행 결과]

ID? hello?
ID Error!
ID? admin
Password? 123123
Password Error!
ID? admin
Password? abc123
Login Successful!
ID? .
  • 5번 문제

4번 문제의 프로그램에 로그인 실패시 아이디를 새로 등록하는 기능을 추가

Password.txt

admin abc123
pizza beer
coke pepsi
Mac Ms
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> // strcmp()함수
#define SIZE 10
struct Login {
	char ID[SIZE] = "";
		char Password[SIZE] = "";
};
int main(void) {
	struct Login a[20];
	char ID[SIZE];
	char Password[SIZE];
	char yesno;
	int count = 4;
	FILE* fp;
	// 파일을 읽기 전용으로 불러옴
	fp = fopen("password.txt", "r");
	// 텍스트에 저장된 정보를 구조체로 가져옴
	for (int i = 0; i < 4; i++) {
		fscanf(fp, "%s %s", &a[i].ID, &a[i].Password);
	}
	fclose(fp);
	for (;;) {
	start:
		printf("ID?  ");
		scanf("%s", ID);
		// .을 입력하면 프로그램 종료
		if (*ID == '.')
			break;
		for (int i = 0; i < 20; i++) {
			// ID 비교
			if (!strcmp(ID, a[i].ID)) {
				getchar();
				printf("Password?  ");
				scanf("%s", Password);
				// Password 비교
				if (!strcmp(Password, a[i].Password)) {
					printf("Login Successful!\n");
					goto start;
				}
				printf("Password Error!\n");
				goto start;
			}
		}
		printf("Add ID?  ");
		getchar();
		scanf("%c", &yesno);
		// ID 추가 Y/N 
		if ((yesno == 'Y') || (yesno == 'y')) {
			// Y 입력시 ID를 구조체에 저장
			strncpy(a[count].ID, ID, SIZE);
		PW:
			// Password 입력
			printf("Password?  ");
			scanf("%s", a[count].Password);
			// Password를 한번 더 입력받아 구조체에 저장된 Pasword와 비교
			printf("Password again?  ");
			scanf("%s", Password);
			// Password 일치 시 ID PW 추가 성공문자 출력
			if (!strcmp(a[count].Password, Password)) {
				printf("ID and Password registered Successful!\n");
				count++;
				goto start;
			}
			printf("Password doesn't match!\n");
			goto PW;
		}
	}
	// Login 구조체에 저장된 내용을 파일로 출력
	fp = fopen("password.txt", "w");
	fwrite(&a, sizeof(struct Login), count, fp);
	fclose(fp);
	return 0;
}
[실행 결과]

ID?  Love_Pepsi
Add ID?  Y
Password?  cokecoke
Password again?  pepsipepsi
Password doesn't match!
Password?  noob_coke
Password again?  noob_coke
ID and Password registered Successful!
ID?  .
  • 6번 문제

커피숍의 계산서를 텍스트 파일로 저장하는 프로그램

receipt.txt

제품명		단가	수량	금액
-------------------------------------
아메리카노	4000	   2	8000
카페라떼  	4500	   1	4500
-------------------------------------
결제 금액 :                     12500
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define SIZE 100
int main(void) {
	int arr[5];
	int price[3] = { 4000,4500,5000 };
	char menu[4][SIZE] = {
		{"아메리카노"},
		{"카페라떼"},
		{"플랫화이트"},
		{"결제 금액"}
	};
	// 메뉴를 출력하고 주문을 받음
	printf("[메뉴] %5s:%d, %5s:%d, %5s:%d\n", menu[0], price[0], menu[1], price[1], menu[2], price[2]);
	printf("%-10s 수량? ", menu[0]);
	scanf("%d", &arr[0]);
	printf("%-10s 수량? ", menu[1]);
	scanf("%d", &arr[1]);
	printf("%-10s 수량? ", menu[2]);
	scanf("%d", &arr[2]);
	arr[3] = (arr[0] * 4000) + (arr[1] * 4500) + (arr[2] * 5000);
	printf("%-10s: %d", menu[3], arr[3]);
	// receipt.txt 파일을 열고 주문받은 내용을 토대로 계산서 출력
	FILE* fp;
	fp = fopen("receipt.txt", "w");
	fputs("제품명		단가	수량	금액\n", fp);
	fputs("-------------------------------------\n", fp);
	// 주문 받은 수가 0인 메뉴는 출력하지 않음
	if (arr[0] != 0)
		fprintf(fp, "%-10s	%d	%4d	%4d\n", menu[0], price[0], arr[0], arr[0] * price[0]);
	if (arr[1] != 0)
		fprintf(fp, "%-10s	%d	%4d	%4d\n", menu[1], price[1], arr[1], arr[1] * price[1]);
	if (arr[2] != 0)
		fprintf(fp, "%-10s	%d	%4d	%4d\n", menu[2], price[2], arr[2], arr[2] * price[2]);
	fputs("-------------------------------------\n", fp);
	fprintf(fp,"%-10s:%27d", menu[3], arr[3]);
	fclose(fp);
	return 0;
}
[실행 결과]

[메뉴] 아메리카노:4000, 카페라떼:4500, 플랫화이트:5000
아메리카노 수량? 2
카페라떼   수량? 1
플랫화이트 수량? 0
결제 금액 : 12500
  • 7번 문제

6번 문제의 계산서 프로그램에서 기능을 추가해 모든 제품의 수량이 0을 입력 받을때까지 반복 수행하고 그 모든 값을 텍스트 파일로 저장해 출력하는 프로그램

receipt.txt

제품명		단가	수량	금액
--------------------------------------------------
아메리카노	4000	   1	4000
카페라떼  	4500	   2	9000
플랫화이트	5000	   3	15000
--------------------------------------------------
결제 금액 :                              28000

제품명		단가	수량	금액
--------------------------------------------------
아메리카노	4000	   1	4000
플랫화이트	5000	   1	5000
--------------------------------------------------
결제 금액 :                               9000

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define SIZE 100
int main(void) {
	int arr[4];
	int price[3] = { 4000,4500,5000 };
	char menu[4][SIZE] = {
		{"아메리카노"},
		{"카페라떼"},
		{"플랫화이트"},
		{"결제 금액"}
	};
	FILE* fp;
	fp = fopen("receipt.txt", "w");
	for (;;) {
		// 메뉴를 출력하고 주문을 받음
		printf("[메뉴] %5s:%d, %5s:%d, %5s:%d\n", menu[0], price[0], menu[1], price[1], menu[2], price[2]);
		printf("%-10s 수량? ", menu[0]);
		scanf("%d", &arr[0]);
		printf("%-10s 수량? ", menu[1]);
		scanf("%d", &arr[1]);
		printf("%-10s 수량? ", menu[2]);
		scanf("%d", &arr[2]);
		arr[3] = (arr[0] * 4000) + (arr[1] * 4500) + (arr[2] * 5000);
		printf("%-10s: %d\n", menu[3], arr[3]);
		// arr[3]의 금액이 0일때 break해도 같은 결과
		if ((arr[0] == 0) && (arr[1] == 0) && (arr[2] == 0))
			break;
		// receipt.txt 파일을 열고 주문받은 내용을 토대로 계산서 출력
		
		fputs("제품명		단가	수량	금액\n", fp);
		fputs("--------------------------------------------------\n", fp);
		// 주문 받은 수가 0인 메뉴는 출력하지 않음
		if (arr[0] != 0)
			fprintf(fp, "%-10s	%d	%4d	%4d\n", menu[0], price[0], arr[0], arr[0] * price[0]);
		if (arr[1] != 0)
			fprintf(fp, "%-10s	%d	%4d	%4d\n", menu[1], price[1], arr[1], arr[1] * price[1]);
		if (arr[2] != 0)
			fprintf(fp, "%-10s	%d	%4d	%4d\n", menu[2], price[2], arr[2], arr[2] * price[2]);
		fputs("--------------------------------------------------\n", fp);
		fprintf(fp, "%-10s:%35d\n\n", menu[3], arr[3]);
	}
	fclose(fp);
	return 0;
}
[실행 결과]

[메뉴] 아메리카노:4000, 카페라떼:4500, 플랫화이트:5000
아메리카노 수량? 1
카페라떼   수량? 2
플랫화이트 수량? 3
결제 금액 : 28000
[메뉴] 아메리카노:4000, 카페라떼:4500, 플랫화이트:5000
아메리카노 수량? 1
카페라떼   수량? 0
플랫화이트 수량? 1
결제 금액 : 9000
[메뉴] 아메리카노:4000, 카페라떼:4500, 플랫화이트:5000
아메리카노 수량? 0
카페라떼   수량? 0
플랫화이트 수량? 0
결제 금액 : 0
  • 8번 문제

2개의 텍스트 파일을 비교하는 프로그램

readme.txt

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
READMEPZ.txt

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define SIZE 100
int main(void) {
	char text_filename_A[SIZE];
	char text_filename_B[SIZE];
	char A, B;
	FILE* fpA;
	FILE* fpB;
	// 파일의 이름을 입력받음
	printf("원본 파일? ");
	scanf("%s", text_filename_A);
	printf("타겟 파일? ");
	scanf("%s", text_filename_B);
	// 파일을 불러옴
	fpA = fopen(text_filename_A, "r");
	fpB = fopen(text_filename_B, "r");
	// 파일 불러오기 실패시 Error! 출력과 함께 종료
	if (fpA == NULL || fpB == NULL) {
		printf("Error!\n");
		return 1;
	}
	for (;;) {
		if (feof(fpA) == 0 && feof(fpB) == 0) {
			// 파일에 저장된 문자를 한 문자씩 A,B로 전달
			A = fgetc(fpA);
			B = fgetc(fpB);
			// foeof() 함수를 사용해 비교
			if (A != B) {
				printf("두 파일은 다릅니다.\n");
				break;
			}
			else if (feof(fpA) != 0 && feof(fpB) == 0) {
				printf("두 파일은 다릅니다.\n");
				break;
			}
			else if (feof(fpA) == 0 && feof(fpB) != 0) {
				printf("두 파일은 다릅니다.\n");
				break;
			}
			else {
				printf("두 파일이 같습니다.\n");
				break;
			}
		}
	}
	fclose(fpA);
	fclose(fpB);
}
[실행 결과]

원본 파일? readme.txt
타겟 파일? READMEPZ.txt
두 파일이 같습니다.
  • 9번 문제

텍스트와 키를 입력받아 시저 암호로 암호화한 후 텍스트 파일로 출력하는 프로그램

시저 암호는 각 알파벳을 특정 갯수만큼 더하고 빼서 다른 알파벳으로 치환하는 간단한 암호화 방식이다.

cipher.txt

Ixq Ixq F Surjudpplqj.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h> //strlen()함수
#define SIZE 100
int main(void) {
	char text_contents[SIZE];
	int key, k = 0;
	FILE* fp;;
	fp = fopen("cipher.txt", "w");
	printf("암호 키? ");
	scanf("%d", &key);
	getchar();
	printf("암호화할 텍스트?\n");
	// %[^\n]s 를 사용해 \n을 제외한 모든 문자를 입력받음
	scanf("%[^\n]s", text_contents);
	
	// text_contents[i]에 A(ASCII 65)를 빼서 A를 0으로 만들어 기준을 잡고 key의 값만큼 더한다.
	for (size_t i = 0; i < strlen(text_contents); i++) {
		if (text_contents[i] >= 'A' && text_contents[i] <= 'Z') {
			text_contents[i] -= 'A';
			if (text_contents[i] + key < 0) {
				text_contents[i] += 26;
			}
			// 알파벳은 26문자로 이루어져있기에 26보다 큰값을 버리는것
			text_contents[i] = (text_contents[i] + key) % 26;
			// 나머지값에 A를 더해 ASCII코드를 맞춘다.
			text_contents[i] += 'A';
		}
		if (text_contents[i] >= 'a' && text_contents[i] <= 'z') {
			text_contents[i] -= 'a';
			if (text_contents[i] + key < 0) {
				text_contents[i] += 26;
			}
			text_contents[i] = (text_contents[i] + key) % 26;
			text_contents[i] += 'a';
		}
	}
	// 파일에 암호화한 텍스트를 저장하고 파일을 닫음.
	fputs(text_contents, fp);
	fclose(fp);
}
[실행 결과]

암호 키? 3
암호화할 텍스트?
Fun Fun C Programming.
  • 10번 문제

9번 문제에서 만든 시저 암호화된 파일을 복호화 시키는 프로그램

cipher.txt

Ixq Ixq F Surjudpplqj.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(void) {
	char text_filename[SIZE];
	char text_contents[SIZE];
	int key;
	FILE* fp;
	// 파일 이름을 입력받고 불러옴
	printf("복호화할 파일? ");
	gets_s(text_filename, SIZE);
	fp = fopen(text_filename, "r");
	// 파일을 찾지 못하면 Error! 출력 후 종료
	if (fp == NULL) {
		printf("Error!\n");
		return 1;
	}
	// 복호 키를 입력받음 
	printf("복호 키? ");
	scanf("%d", &key);
	key = -key;
	// text_contents[i]에 A(ASCII 65)를 빼서 A를 0으로 만들어 기준을 잡고 key의 값만큼 뺀다.
	while (!feof(fp)) {
		fgets(text_contents, SIZE, fp);
		for (size_t i = 0; i < strlen(text_contents); i++) {
			if (text_contents[i] >= 'A' && text_contents[i] <= 'Z') {
				text_contents[i] -= 'A';
				if (text_contents[i] + key < 0) {
					text_contents[i] += 26;
				}
				// 알파벳은 26문자로 이루어져있기에 26보다 큰값을 버림
				text_contents[i] = (text_contents[i] + key) % 26;
				text_contents[i] += 'A';
			}
			if (text_contents[i] >= 'a' && text_contents[i] <= 'z') {
				text_contents[i] -= 'a';
				if (text_contents[i] + key < 0) {
					text_contents[i] += 26;
				}
				text_contents[i] = (text_contents[i] + key) % 26;
				text_contents[i] += 'a';
			}
		}
	}
	// 복호화한 암호를 출력하고 파일을 닫음
	printf("%s\n", text_contents);
	fclose(fp);
}
[실행 결과]

복호화할 파일? cipher.txt
복호 키? 3
Fun Fun C Programming.
  • 11번 문제

구조체 형식의 동적 메모리를 할당하고 연락처가 저장된 파일을 불러와 동적 메모리에 입력시킨 연락처를 찾는 프로그램

mycontact.txt

노진구 01012345678
퉁퉁이 01000000000
이슬이 01011111111
비실이 01022222222
도라에몽 01033333333
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // malloc()함수
#include <string.h> // strcmp()함수
#define SIZE 100
struct CONTACT {
	char name[SIZE];
	unsigned int num;
};
int main(void) {
	char text_filename[SIZE];
	char name[SIZE];
	int struct_size = 5;

	// 연락처가 저장되어있는 파일 불러오기
	FILE* fp;
	printf("연락처 파일명? ");
	gets_s(text_filename, SIZE);
	fp = fopen(text_filename, "r");

	// 동적 메모리 할당
	CONTACT* arr;
	arr = (struct CONTACT*)malloc(sizeof(struct CONTACT) * struct_size);

	// 동적 메모리에 파일에 저장된 연락처 입력
	for (int i = 0; i < struct_size; i++) {
		fscanf(fp, "%s %d", &arr[i].name, &arr[i].num);
	}
	fclose(fp);
	printf("%d개의 연락처를 로딩했습니다.\n", struct_size);
	
	for (;;) {
		start:
		printf("이름(. 입력 시 종료)? ");
		scanf("%s", name);
		// . 입력시 프로그램 종료
		if (*name == '.')
			break;
		// 동적 메모리에 저장된 이름과 입력받은 이름을 비교
		for (int i = 0; i < struct_size; i++) {
			if (!strcmp(name, arr[i].name)) {
				printf("%s의 전화번호 %d로 전화를 겁니다....\n", arr[i].name, arr[i].num);
				goto start;
			}
		}
		printf("연락처를 찾을 수 없습니다.\n");
	}
	free(arr);
}
[실행 결과]

연락처 파일명? mycontact.txt
5개의 연락처를 로딩했습니다.
이름(. 입력 시 종료)? 노진구
노진구의 전화번호 01012345678로 전화를 겁니다....
이름(. 입력 시 종료)? 도라에몽
도라에몽의 전화번호 01033333333로 전화를 겁니다....
이름(. 입력 시 종료)? .
  • 12번 문제

11번 문제의 프로그램에서 연락처를 찾을 수 없으면 연락처를 추가하고 'CONTACT' 구조체의 내용을 텍스트 파일로 출력하는 기능을 추가한 프로그램

List.txt

노진구 01012345678
퉁퉁이 01000000000
이슬이 01011111111
비실이 01022222222
도라에몽 01033333333
홍길동 01099999999
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // malloc()함수
#include <string.h> // strcmp()함수
#define SIZE 100
struct CONTACT {
	char name[SIZE];
	unsigned int num;
};
int main(void) {
	char text_filename[SIZE];
	char name[SIZE];
	int struct_size = 5;
	char yesno;

	// 연락처가 저장되어있는 파일 불러오기
	FILE* fp;
	printf("연락처 파일명? ");
	gets_s(text_filename, SIZE);
	fp = fopen(text_filename, "r");

	// 동적 메모리 할당
	CONTACT* arr;
	arr = (struct CONTACT*)malloc(sizeof(struct CONTACT) * struct_size);

	// 동적 메모리에 파일에 저장된 연락처 입력
	for (int i = 0; i < struct_size; i++) {
		fscanf(fp, "%s%d", &arr[i].name, &arr[i].num);
	}
	fclose(fp);
	printf("%d개의 연락처를 로딩했습니다.\n", struct_size);

	for (;;) {
	start:
		printf("이름(. 입력 시 종료)? ");
		scanf("%s", name);
		// . 입력시 프로그램 종료
		if (*name == '.')
			break;
		// 동적 메모리에 저장된 이름과 입력받은 이름을 비교
		for (int i = 0; i < struct_size; i++) {
			if (!strcmp(name, arr[i].name)) {
				printf("%s의 전화번호 %d로 전화를 겁니다....\n", arr[i].name, arr[i].num);
				goto start;
			}
		}
		printf("연락처를 찾을 수 없습니다.\n");
		printf("연락처를 등록하시겠습니까? (Y/N)\n");
		getchar();
		scanf("%c", &yesno);
		// Y를 입력받으면 이름을 복사하고 전화번호를 입력받음
		if ((yesno == 'Y') || (yesno == 'y')) {
			strncpy(arr[struct_size].name, name, SIZE);
			printf("전화번호? ");
			scanf("%d", &arr[struct_size].num);
			struct_size++;
			goto start;
		}
	}
	// 동적 메모리에 저장된 이름, 전화번호를 파일로 출력
	fp = fopen(text_filename, "w");
	for (int i = 0; i < struct_size; i++) {
		fprintf(fp, "%s %d\n", arr[i].name, arr[i].num);
	}
	fclose(fp);
	free(arr);
}
[실행 결과]

연락처 파일명? List.txt
5개의 연락처를 로딩했습니다.
이름(. 입력 시 종료)? 도라에몽
도라에몽의 전화번호 01033333333로 전화를 겁니다....
이름(. 입력 시 종료)? 홍길동
연락처를 찾을 수 없습니다.
연락처를 등록하시겠습니까? (Y/N)
Y
전화번호? 01099999999
이름(. 입력 시 종료)? 홍길동
홍길동의 전화번호 01099999999로 전화를 겁니다....
이름(. 입력 시 종료)? .
  • 13번 문제

N을 입력받아 N 크기의 동적 메모리를 할당해 난수로 채우고 텍스트 파일과 2진 파일로 각각 저장하는 프로그램

A.txt

12db
7f0d
50a9
2cf1
29b4
A.dat

열어볼 방법을 모르겠음..
크기는 동일한 내용임에도 .dat이 작음
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> //malloc()함수, srand()함수, atoi()함수
#include <time.h> // time()함수
#include <string.h> // strcat()함수, strtok()함수
#define SIZE 50
int main(void) {
	srand(time(NULL));
	int num;
	int* N = NULL;
	char name[SIZE];
	char ext[2][SIZE] = { 
		{".txt"},
		{".dat"}
	};
	printf("정수의 개수? ");
	scanf("%d", &num);
	printf("파일명? ");
	scanf("%s", name);
	// 동적 메모리 할당
	N = (int*)malloc(sizeof(int) * num);
	if (N == NULL){
		printf("Error!\n");
		return 1;
	}
	// .txt 확장자 추가
	strcat(name, ext[0]);
	FILE* fp10;
	fp10 = fopen(name, "w");

	if (fp10 == NULL) {
		printf("Error!\n");
		return 1;
	}
	// name.txt에서 .txt 삭제 후 name.dat으로 변경
	char* ptr = strtok(name, ".");
	strcat(ptr, ext[1]);
	FILE* fp2;
	fp2 = fopen(ptr, "wb");

	if (fp2 == NULL) {
		printf("Error!\n");
		return 1;
	}
	// rand()함수로 0~99사이의 난수를 입력
	for (int i = 0; i < num; i++) {
		N[i] = rand();
		fprintf(fp10, "%d", N[i]);
		fprintf(fp2, "%02x", N[i]);
	}
	// 확장자 지우기
	char* ptr2 = strtok(name, ".");
	printf("%s.txt와 %s.dat을 생성했습니다.\n", ptr2, ptr2);
	// 할당된 동적 메모리와 파일 초기화
	fclose(fp10);
	fclose(fp2);
	free(N);
}
[실행 결과]

정수의 개수? 5
파일명? A
A.txt와 A.dat을 생성했습니다.
  • 14번 문제

13번 문제의 프로그램에서 생성한 2개의 .dat 파일을 불러오고 정수의 갯수를 출력하고 두 파일을 합친 파일을 생성하는 프로그램

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // qsort()함수, atoi()함수
#include <string.h> // strcmp()함수
#define SIZE 300
#define MAX 32767
int compare(const void* a, const void* b) {
	return (strcmp((char*)a, (char*)b));
}
int main(void) {
	char dat_filename1[SIZE];
	char dat_filename2[SIZE];
	char dat_filename3[SIZE];
	char temp[SIZE];
	int size1 = 0, size2 = 0, size3 = 0;
	int arr[MAX];
	int i = 0;

	FILE* fp1;
	printf("첫 번째 파일명? ");
	gets_s(dat_filename1, SIZE);
	fp1 = fopen(dat_filename1, "rb");
	// 일치하는 파일명을 발견하지 못하면 Error!
	if (fp1 == NULL) {
		printf("Error!\n");
		return 1;
	}
	// \n을 찾아 카운팅하고 arr에 정수 저장
	while (!feof(fp1)) {
		fgets(temp, SIZE, fp1);
		arr[i] = atoi(temp);
		i++;
		if (temp[strlen(temp) - 1] == '\n') {
			size1++;
		}
	}
	printf("정수 %d개를 읽었습니다.\n", size1);

	FILE* fp2;
	printf("두 번째 파일명? ");
	gets_s(dat_filename2, SIZE);
	fp2 = fopen(dat_filename2, "rb");
	// 일치하는 파일명을 발견하지 못하면 Error!
	if (fp2 == NULL) {
		printf("Error!\n");
		return 1;
	}
	// \n을 찾아 카운팅하고 arr에 정수 저장
	while (!feof(fp2)) {
		fgets(temp, SIZE, fp2);
		arr[i] = atoi(temp);
		i++;
		if (temp[strlen(temp) - 1] == '\n') {
			size2++;
		}
	}
	printf("정수 %d개를 읽었습니다.\n", size2);

	FILE* fp3;
	printf("저장할 파일명? ");
	gets_s(dat_filename3, SIZE);
	fp3 = fopen(dat_filename3, "w+b");
	// arr에 저장된 정수를 qsort함수를 사용해 정렬
	qsort((void*)arr, i, sizeof(arr[0]), compare);
	// 정렬된 arr를 fp3에 입력
	for (int k = 0; k < i; k++) {
		fprintf(fp3, "%d\n", arr[k]);
	}
	printf("정수 %d개를 저장했습니다.\n", i);

	fclose(fp1);
	fclose(fp2);
	fclose(fp3);

	return 0;
}
[실행 결과]

첫 번째 파일명? a.dat
정수 181개를 읽었습니다.
두 번째 파일명? b.dat
정수 75개를 읽었습니다.
저장할 파일명? c.dat
정수 256개를 저장했습니다.
Clone this wiki locally