[C] 9. file (파일 입출력)

Kim Dongil·2022년 10월 12일
0

C

목록 보기
10/28

파일쓰기, 파일읽기

파일쓰기(fputs), 파일읽기(fgets)
또 다른 파일읽기(fprintf), 또 다른 파일읽기(fscanf)

파일의 데이터를 읽고 쓰기 메모리상에 저장이 된다. 프로그램을 끄면 메모리 에 저장된게 날라가기 때문에 그 변수값이 똑같이 유지안되지만 파일로 저장하면 변도의 공간에 저장되어서 꺼다 켜도 다시 유용허게 쓸수 있다.

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#define MAX 10000

int main(void)
{
	// 파일 입출력 
	// 파일에 어떤 데이터를 저장.
	// 파일에 저장된 데이터를 불러오기 

	// fputs, fgets 쌍 > 문자열 저장 
	 char line[MAX]; // char line[10000]

	// 파일에 쓰기 
	FILE* file = fopen("c:\\test1.txt", "wb"); // r 읽기전용 w 쓰기전용 a 이어쓰기 t 텍스트 b 바이널 데이터
	if (file == NULL)
	{
		printf("파일 열기 실패\n");
		return 1;
	}

	fputs("fputs 를 이용해서 글을 적어볼게요\n", file);
	fputs("잘 적히는지 확인해주세요 \n", file);
	
	// 파일 읽기
	FILE* file = fopen("c:\\test1.txt", "rb");
	if (file == NULL)
	{
		printf("파일 열기 실패\n");
		return 1;
	}

	while (fgets(line, MAX, file) != NULL)
	{
		printf("%s", line);
	}
	// 파일을 열고 나서 닫지 않은 상태에서 어떤 프로그램에 문제가 생기면? 
	// 데이터 손실 발생 가능 ! 그래서 항상 파일은 닫아주는 습관을 들여주세요
	 fclose(file); 

	
	// fprintf, fscanf 쌍 
	// printf("%d %d %s ... ") 
	// scanf("%d %d", &num1, ...)
	int num[6] = { 0, 0, 0, 0, 0, 0, }; // 로또 추첨번호
	int bonus = 0; // 보너스 번호
	char str1[MAX];
	char str2[MAX];

	// 파일에 쓰기
	FILE* file = fopen("c:\\test2.txt", "wb");
	if (file == NULL)
	{
		printf("파일 열기 실패\n");
		return 1;
	}

	// 로또 추첨 번호 저장
	fprintf(file, "%s %d %d %d %d %d %d\n", "추첨 번호", 1, 2, 3, 4, 5, 6);
	fprintf(file, "%s %d\n", "보너스번호", 7);

	// 파일 읽기
	FILE* file = fopen("c:\\test2.txt", "rb");
	if (file == NULL)
	{
		printf("파일 열기 실패\n");
		return 1;
	}
	fscanf(file, "%s %d %d %d %d %d %d", str1,
		&num[0], &num[1], &num[2], &num[3], &num[4], &num[5]);
	printf("%s %d %d %d %d %d %d\n", str1,
		num[0], num[1], num[2], num[3], num[4], num[5]);

	fscanf(file, "%s %d", str2, &bonus);
	printf("%s %d\n", str2, bonus);

	fclose(file);

	
	return 0;
}
  • #define _CRT_SECURE_NO_WARNINGS 사용하는 이유

안전성의 이유로 Visual Studio 2005 이상부터 경고가 발생합니다.SECURE 모드로 scanf_s 로 사용해서 해결을 하라고 하지만, 다른 곳에서 사용하기에는 호환성의 문제가 많습니다. (Visual Studio 에서만 지원합니다.)

#define MAX 10000
#define PI 3.14
#define TAX_RATE 1.6

위와 같이 지정하게 되면, 앞으로 도크에서 MAX 값이 10000, PLdms 3.14, TAX_RATE는 1.6이 된다. 단순히 숫자를 기입해도 상관없지만 위와 같이 기호상수를 정의하게 되면

  1. 가독성이 매우 높아진다. 1.6을 아무리 쳐다본들 뭔지 알수 없지만 TAX_RATE 라고 써놓으면 아 이건 세율이구나. 라고 인지 가능
  2. 상수의 변경이 매우 용이해진다. 1.6이라고 코드에 짖겁 써놓았다면 TAX_RATE가 만일 1.7이 되어서 변경해야 될 경우, 해당 부분을 모두 찾아서 변경해야 하지만 기호상수를 정의하면 바로 위의 한줄만 수정하면 된다.

기호 상수 : 기호를 이용하여 상수를 표기한 것

파일은 대표적으로 두가지 종류

  • 텍스트 파일(Text files)
  1. 확장자가 .txt로 된 파일
  2. 사람의 눈으로 쉽게 읽을 수 있음
  3. 눈으로 확인 가능하기 때문에 수정이 편리하고 읽기도 편함
  4. 데이터가 그대로 노출되는 문제가 발생
  • 바이너리 파일(Binary files)
  1. 컴퓨터를 위한 파일
  2. 눈으로 식별 x 기계가 식별 0 or 1 로 만들어진 데이터를 저장한 파일
  3. 텍스트에 비해서 더 많은 양을 저장할 수 있지만, 눈으로 식별이 쉽지 않고 데이터가 그대로 노출되지는 않기 때문에 조금 더 안전함

Project 비밀일기

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

// 비밀번호를 입력 받아서 
// 맞는 경우? 비밀 일기를 읽어와서 보여주고, 계속 작성하도록 합니다.
// 틀린 경우? 경고 메시지를 표시하고 종료합니다. 

#define MAX 10000

int main(void)
{
	// fgets, fputs 활용 
	char line[MAX]; // 파일에서 불러온 내용을 저장할 변수 
	char contents[MAX]; // 일기장에 입력할 내용 
	char password[20]; // 비밀번호 입력
	char c; // 비밀번호 입력 할 때 키값 확인용 (마스킹)
	
	printf("'비밀일기' 에 오신것을 환영합니다 \n");
	printf("비밀번호를 입력하세요 : ");

	// getchar() / getch() 의 차이? 
	// getchar() : 엔터를 입력받아야 동작을 합니다.
	// getch() : 키 입력 시 바로바로 동작을 합니다.

	int i = 0;
	while (1)
	{
		c = getch();
		if (c == 13) // enter > 비밀번호 입력 종료 
		{
			password[i] = '\0';
			break;
		}
		else // 비밀번호 입력 중 
		{
			printf("*");
			password[i] = c;
		}
		i++;
	}
	// 비밀번호 : 나도 코딩 skehzheld
	printf("\n\n === 비밀번호 확인 중... ===  \n\n");
	if (strcmp(password, "skehzheld") == 0) // 비밀번호 일치
	{
		printf(" === 비밀번호 확인 완료 === \n\n");
		char* fileName = "c:\\secretdiary.txt";
		FILE* file = fopen(fileName, "a+b"); 
		// 파일이 없으면 생성, 있으면 append 를 한다 (뒤에서부터 내용을 추가한다)
		if (file == NULL)
		{
			printf("파일 열기 실패\n");
			return 1;
		}

		while (fgets(line, MAX, file) != NULL)
		{
			printf("%s", line);
		}

		printf("\n\n 내용을 계속 작성하세요 ! 종료하시려면 EXIT 를 입력하세요 \n\n");

		while (1)
		{
			scanf("%[^\n]", contents); // 세 줄(\n)이 나오기 전까지 읽어들임 (한 문장씩)
			getchar(); // Enter 입력 (\n) Flush 처리

			if (strcmp(contents, "EXIT") == 0)
			{
				printf("비밀일기 입력을 종료합니다 \n\n");
				break;
			}
			fputs(contents, file);
			fputs("\n", file); // Enter 를 위에서 무시 처리 하였으므로 임의로 추가
		}
		fclose(file);
	}
	else // 비밀번호 틀린 경우
	{
		printf(" === 비밀번호가 틀렸어요 === \n\n");
	}

	return 0;
}

strcmp : 매개변수로 들어온 두개의 문자열을 비교 하여 문자열이 완전히 같다면 0을 반환하고, 다르면 음수 혹은 양수를 반환하는 함수입니다.
여기서 -1, 1은 매개변수로 들어온 문자열들을 비교하다가 다른 문자가 나왔을때 그 문자의 아스키 코드 값에 의해서 정해집니다.

C 언어 무료 강의 (입문부터 게임 개발까지)
파일 다루는 함수 사용 방법
#define _CRT_SECURE_NO_WARNINGS를 사용하는 이유?
C언어 전처리기(#define 매크로)
2022-08-09 파일 쓰기 읽기
[C언어/C++] strcmp, strncmp 함수(문자열 비교)에 대해서

0개의 댓글