840 likes | 991 Views
Chapter 4. 보조자료 - 파일 입출력. 파일의 기본 개념과 특징을 이해한다 . 파일 처리 과정을 이해한다 . 형식을 지정한 파일 입출력 fscanf / fprintf 를 배운다 . 문자 단위 입출력 fgetc / fputc 를 배운다 . 문자열 단위 입출력 fgets / fputs 를 배운다 . 이진 파일 입출력 fread / fwrite 를 배운다 . 임의 접근을 통한 파일 입출력을 위한 fseek , rewind, ftell 을 배운다. 개 요. input.txt.
E N D
Chapter 4. 보조자료 - 파일 입출력 파일의 기본 개념과 특징을 이해한다. 파일 처리 과정을 이해한다. 형식을 지정한 파일 입출력 fscanf/fprintf를 배운다. 문자 단위 입출력 fgetc/fputc를 배운다. 문자열 단위 입출력 fgets/fputs를 배운다. 이진 파일 입출력 fread/fwrite를 배운다. 임의 접근을 통한 파일입출력을 위한 fseek, rewind, ftell을 배운다.
개 요 input.txt C 프로그램 키보드 (표준 입력 장치) • 표준 입출력과 파일 입출력 • 표준 입출력의 문제점 • 키보드 입력: 실행 마다 똑같은 데이터를 입력 • 모니터 출력: 실행 결과 창 스크롤링, 결과 창을 닫으면 출력 내용이 사라짐 • 해결: 데이터를 저장한 파일로부터 입력을 받고 결과를 파일로 저장하기 20 파일에서 읽기 입력 age 변수 20 출력 output.txt 파일에 쓰기 • 나이: 20세 모니터 (표준 출력 장치)
개 요 • 스트림(stream) 기반의 입출력 • stream - 연속된 데이터 바이트의 흐름 • 표준 입출력 함수 : printf함수, scanf함수 • 키보드나 모니터를 포함하여 모든 주변장치들을 파일처럼 취급 • 모든 입력과 출력은 공통된 접속(인터페이스)를 사용하여 파일로 취급되는 주변장치들과 연결 • 그 밖의 표준 입출력 함수
개 요 • 표준 입출력장치를 통한 입출력과 파일을 통한 입출력 예 모니터 (표준 출력 장치) C 프로그램 키보드 (표준 입력 장치) age 변수 입력 출력 나이: 20세 20 scanf(“%d”, &age) printf(“나이:%d세”, age) C 프로그램 fp1에 연결된 파일 fp2에 연결된 파일 age 변수 파일에서 읽기 파일에 쓰기 20 • 나이: 20세 20 fscanf(fp1, “%d”, &age) fprintf(fp2, “나이:%d세”, age)
파일이란? • 파일(file) • 보조기억장치에 저장된 물리적인 데이터 집합체 • 저장된 내용의 용도에 따라 프로그램 파일과 데이터 파일로 구분 응용 관리 프로그램 한글 프로그램 포토샵 프로그램 실험 관리 프로그램 Binary Mode Text Mode 과제.hwp 풍경.jpg 분석결과.txt TEST.exe
파일 처리 과정 • 파일 입출력 네 단계 파일 입력프로그램 키보드 입력프로그램 ①파일 포인터 선언 : scanf("%d", &age); scanf("%d", &height); : FILE * fp; : fp = fopen(“data.txt", “r"); : fscanf(fp, "%d", &age); fscanf(fp, "%d", &height); : fclose(fp1); ②파일 열기 ③파일 읽기 (파일에서 읽은 데이터를 변수에 저장) ④파일 닫기 프로그램 변수 프로그램 변수 fp에 연결된 data.txt 파일 키보드 age age fp 20 170 20 170 20 20 height height 170 170
파일 포인터 선언하기 • 파일포인터 선언과 파일 열기 • 파일 포인터가 할당되어 있는 파일에 대해서만 읽기/쓰기가 가능 → 파일 열기를 통해 파일 포인터를 파일에 연결해야 함 • 형식: “파일명” 파일을 열기 FILE *파일포인터명; 파일포인터명= fopen(“파일명”, “모드”); → “파일명”의 파일을 “모드”에 맞게 열며 파일포인터가 열린 파일을 가리키게 된다. • “r”: 읽기 전용, “r+” 읽기/쓰기용 • →“파일명”의 파일이 없다면 에러로 NULL 반환 • “w”: 쓰기 전용, “w+” 읽기/쓰기용 • → 파일 내용을 모두 지움, “파일명”의 파일이 없다면 새로 만듬 • “a”: 추가 전용, “a+” 읽기/쓰기 추가용 • → 파일의 끝에 데이터를 추가, “파일명”파일이 없다면 새로 만듬 • “b”: Binary mode에서 입출력
파일 열기 : fopen함수 • 파일 포인터 선언과 파일 열기 예 • 파일의 위치 • 특별히 위치를 지정하지 않으면 프로젝트 폴더에 파일이 생성되며 읽기용 파일이라면 미리 프로젝트 폴더에 저장되어 있어야 함 • 프로젝트 폴더에 있지 않다면 “C:\\file\\age.txt”와같이 절대경로를 명시해야 함 // 선언과 동시에 파일 열기 FILE *fp = fopen(“data.txt”, “w”); FILE *fp; fp = fopen("data.txt", "w"); fp “data.txt”파일 data.txt 파일 fp 쓰기 모드로 열린 빈 파일 “data.txt” 파일의정보를 가진 FILE구조체 쓰기 모드로 열린 빈 파일 단순화하여 fp가 “data.txt” 파일을가리킨다고 생각하는 것이 편리
파일 열기 : fopen함수 • 파일 열기 실패 처리 • fopen 함수가 실패시 NULL이 반환됨 • 열기 에러 처리 코드의 예 • 지정한 이름의 파일이 존재하지 않는 경우의 에러 처리 코드 FILE *fp; fp = fopen("data.txt", "r"); if (fp == NULL) { printf("지정한 이름의 파일을 열 수 없습니다. \n"); exit(1); }
파일 입출력 함수 • 파일 입출력 함수
파일 닫기 : fclose함수 • 파일닫기 • 프로그램 종료 전에 열린 파일들을 닫아야 함 → 닫은 파일에 연결된 파일포인터는 새로운 파일 열기에 사용 가능 • 형식 fclose(파일포인터명); • 예 FILE*fp; fp = fopen("data.txt", "w"); : // 파일에 자료 쓰기 fclose(fp);// 파일 닫기 : fp = fopen(“result.txt", "w");// 파일포인터 재사용 현재 파일포인터에 연결된 파일이 닫기며 파일포인터와의 연결이 해제됨
파일 닫기 : fclose함수 • ferror함수 • 파일 입출력 시 발생하는 에러를 확인 • 리턴 값 : 스트림에 에러가 발생했으면 0을 이 아닌 값을 리턴하고, 에러가 발생하지 않았으면 0을 리턴한다.
형식을 지정한 파일 출력 : fprintf함수 • fprintf 함수 • 지정한 형식에 맞추어 데이터를 파일로 출력 → printf를 사용한 모니터로의 출력과 똑 같은 내용의 결과를 얻음 • 형식 fprintf(파일포인터명, “변환명세 포함한 형식문자열”, 변수명); • 변수 값이 “형식문자열”에 맞게 변환되여 파일포인터에 연결된 파일에 기록됨 • printf 함수 사용한 모니터 출력 결과 그대로 파일에 기록됨 상수 또는 식
형식을 지정한 파일 출력 : fprintf함수 • fprintf함수
형식을 지정한 파일 출력 : fprintf함수 fp • 나이: 20세 • 예) FILE*fp = fopen(“data.txt”, “r”); age = 20; fprintf(fp, "나이: %d세", age); 파일에 쓰기 fprintf (fp, “나이: %d세“, age); C 프로그램 age 변수 20 stdout printf(“나이: %d세“, age); fprintf (stdout, “나이: %d세“, age); 모니터에 출력하기
형식을 지정한 파일 출력 : fprintf함수 • 예) FILE*fp = fopen(“data.txt”, “r”); age = 20; fprintf(fp, "나이: %d세", age);
형식을 지정한 파일 출력 : fprintf함수 • 파일 처리 방식과 구분 Text mode Binary mode
4 – 1 : 회원 5명의 나이 정보를 파일에 저장하기 1 #include <stdio.h> // fopen, fprintf, fclose 함수를 위한 헤더 파일 2 #include <stdlib.h> // exit 함수를 위한 헤더 파일 3 #define SIZE 5 // 회원 수 4 5 int main() 6 { 7 FILE *fp; // 파일 포인터 선언 8 char *f_name = "age.txt"; // 파일명, char f_name[20]="age.txt";도 가능 9 int age, i; 10 11 fp = fopen(f_name, "w"); // fp = fopen("age.txt", "w")도 가능 12 13 if (fp == NULL) // 파일 열기 에러 처리 14 { 15 printf(" %s 파일 열기 에러! \n", f_name); 16 exit(1); 17 } 19 printf("회원 %d명의 나이를 입력하면 파일로 저장합니다.\n", SIZE);
4 – 1 : 회원 5명의 나이 정보를 파일에 저장하기 21 for (i=0; i<SIZE; i++) // SIZE명의 나이를 키보드에서 입력받아 파일에 쓰기 22 { 23 printf("%2d번 회원의 나이는? ", i+1); 24 scanf("%d", &age); // 키보드에서 회원의 나이를 입력받기 25 26 fprintf(fp, "%d\n", age); // age의 값을 fp에 연결된 파일에 쓰기 27 } 28 29 fclose(fp); // fp에 연결된 age.txt 파일을 닫고 연결을 끊기 30 printf("회원 %d명의 나이를 %s 파일에 저장했습니다.\n", SIZE, f_name); 31 32 return 0; 33 } • age.txt 파일의 내용 • 20↲ • 23↲ • 25↲ • 21↲ • 20↲ 실행결과 • 회원 5명의 나이를 입력하면 파일로 저장합니다. • 1번 회원의 나이는? 20 • 2번 회원의 나이는? 23 • 3번 회원의 나이는? 25 • 4번 회원의 나이는? 21 • 5번 회원의 나이는? 20 • 회원 5명의 나이를 age.txt 파일에 저장했습니다
Program 4 – 1 : 회원 5명의 나이 정보를 파일에 저장하기 • 분석 • 키보드로 입력받은 나이를 파일에 쓰는 과정(24, 26행)을 5번 반복하면 파일에 5개의 나이가 저장됨 C 프로그램 fp age.txt 파일 키보드 20↲ 입력 age 변수 출력 20 scanf(“%d”, &age) fprintf(fp, “%d\n”, age)
형식을 지정한 파일 입력 : fscanf함수 • fscanf 함수 • 파일의 데이터를 변환명세로 지정한 형식에 맞게 읽어서변수에 저장 → scanf의키보드 자료 입력과 똑 같은 내용이 파일에 기록되어 있어야 함 • 형식 scanf(파일포인터명, “변환명세”, &변수명) • 파일포인터가 가리키는 파일에서 변환명세 맞게 데이터를 읽어서 변수에 저장 • 읽기 실패 또는 파일의 끝에 도달했다면 EOF를 반환
형식을 지정한 파일 입력 : fscanf함수 • fscanf함수
형식을 지정한 파일 입력 : fscanf함수 • 예) FILE *fp = fopen("read.txt"); fscanf(fp, "%d", &age); fscanf(fp, "%d", &height); 파일에서 읽기 C 프로그램 read.txt 파일 fscanf(fp, “%d”, &age); fp age 변수 20 • 20 • 170 height 변수 170 fscanf(fp, “%d”, &height);
4 – 2 : “age.txt” 파일의 나이 정보를 화면에 출력하기 1 #include <stdio.h> // fopen, fscanf, fclose 함수를 위한 헤더 파일 2 #include <stdlib.h> // exit 함수를 위한 헤더 파일 3 #define SIZE 5 // 회원 수 4 5 int main() 6 { 7 FILE *fp; // 파일 포인터 선언 8 char *f_name = "age.txt"; // 파일명, char f_name[20]="age.txt";도 가능 9 int age, i; 10 11 fp = fopen(f_name, "r"); // f_name 이름의 파일을 읽기용으로 열기 12 13 if (fp == NULL) // 파일 열기 에러 처리 14 { 15 printf(" %s 파일을 열 수 없습니다. \n", f_name); 16 exit(1); 17 }
4 – 2 : “age.txt” 파일의 나이 정보를 화면에 출력하기 19 for (i=0; i<SIZE; i++) // 파일의 나이를 SIZE개 읽어 모니터에 출력하기 20 { 21 // fp에 연결된 파일에서 정수 한 개를 읽어 age에 저장하기 22 fscanf(fp, "%d", &age); 23 24 // age에 저장된 나이를 모니터에 출력하기 25 printf("%2d번 회원의 나이는 %d세 \n", i+1, age); 26 } 27 28 fclose(fp); // fp에 연결된 age.txt 파일을 닫고 연결을 끊기 30 return 0; 31 } • age.txt 파일의 내용 • 20↲ • 23↲ • 25↲ • 21↲ • 20↲ 실행결과 • 1번 회원의 나이는 20세 • 2번 회원의 나이는 23세 • 3번 회원의 나이는 25세 • 4번 회원의 나이는 21세 • 5번 회원의 나이는 20세
fprintf와 fscanf의 주의점 • 주의 • 여러 값을 한꺼번에 파일에 쓸 때 공백 문자(빈칸, 탭키, 엔터키) 넣기 age = 20; height = 170; fprint(fp, "%d%d\n", age, height); 공백 문자가 없다. • 20170 이후 이 파일을 읽기용으로 연 후 fscanf(fp, “%d%d“, &age, &height);를 사용한다면? 20170이 age에 저장되고 height에는 데이터가 입력되지 않음 → 20과 170 사이에 공백 문자를 넣어둬야 한다.
fprintf와 fscanf의 주의점 • 주의 • scanf와 마찬가지로 변환명세에 주의 • 일반 문자 사용 불가 • 필드폭은 생략 • 변환명세 끝에 빈칸이나 ‘\n’넣지 말기 fscanf(fp, "키:%5d ", &height); 빈칸 또는 \n을 넣으면 데이터를 한 개 더 읽게 됨 일반 문자는 불가능 필드폭을사용 않는 것이 더 안전
파일의 추가 • 추가 모드의 필요성 • 쓰기 모드는 기존의 파일 내용을 모두 지우고 새로 쓰기를 함→ 이전 실행 결과와 함께 새 실행 결과도 같은 파일에 저장하고 싶을 때는 추가 모드로 열어야 함 • [프로그램] • [프로그램 4-2]에서 만든 age.txt 파일에 n명의 나이를 추가하는 프로그램 • 파일 작성 두 가지 방법 • 프로그램을 통한 실행 결과로 만들기 • 프로그램에 사용할 데이터를 미리 일반 편집기를 이용하여 파일로 만들기 → 목적에 따라 두 방법 중 선태 가능 → [프로그램]을 실행하지 않고 age.txt 파일을 메모장 또는 비주얼 스튜디오에서 직접 만든 후 [프로그램 4-3]을 실행해도 됨
4 – 3 : age.txt 파일에 n명의 나이 추가하기 1 #include <stdio.h> // fopen, fprintf, fclose 함수를 위한 헤더 파일 2 #include <stdlib.h> // exit 함수를 위한 헤더 파일 3 4 int main() 5 { 6 FILE *fp; // 파일 포인터 선언 7 char *f_name = "age.txt"; // 파일명, char f_name[20]="age.txt";도 가능 8 int age, i, n; 9 10 fp = fopen(f_name, "a"); // f_name 이름의 파일을 추가용으로 열기 11 12 if (fp == NULL) // 파일 열기 에러 처리 13 { 14 printf(" %s 파일 열기 에러! \n", f_name); exit(1); 15 } 추가 모드
4 – 3 : age.txt 파일에 n명의 나이 추가하기 17 printf("회원의 나이를 입력하면 %s 파일에 추가합니다.\n", f_name); 18 printf("추가할 회원의 수는? "); 19 scanf("%d", &n); // 파일에 추가할 회원 나이 개수를 입력 20 21 // n명의 나이를 키보드에서 입력받아 파일에 추가하기 22 for (i=0; i<n; i++) 23 { 24 printf("회원의 나이는? "); 25 scanf("%d", &age); // 키보드에서 회원의 나이를 입력 26 27 fprintf(fp, "%d\n", age); // age에 저장된 나이를 fp에 연결된 파일에 쓰기 28 } 29 fclose(fp); 30 printf("회원 %d명의 나이를 %s 파일에 추가했습니다.\n", n, f_name); 31 32 return 0; 33 }
프로그램 4 – 3 : age.txt 파일에 n명의 나이 추가하기 • 분석 • 실행 전 age.txt 파일의 내용 • 실행 후 age.txt 파일의 내용 • 20↲ • 23↲ • 25↲ • 21↲ • 20↲ 20 23 25 21 20 29 31 27 실행결과 회원의 나이를 입력하면 age.txt 파일에 추가합니다. 추가할 회원의 수는? 3 회원의 나이는? 29 회원의 나이는? 31 회원의 나이는? 27 회원 3명의 나이를 age.txt 파일에 추가했습니다.
학생 평점 파일을 읽어 평점 순위 파일 만들기 • 문제 • 입력 파일: 학생의 이름, 평점이 저장된 students.txt 파일 • 출력 파일: 학생의 이름, 평점, 순위가 저장된 rank.txt 파일 rank.txt 파일 students.txt 파일 나태희 2.31 10↲ 유현빈 4.23 3↲ 나원빈4.42 2↲ 문건영 3.72 8↲ 소지법3.74 7↲ 나보내3.85 5↲ 장도건 4.06 4↲ 고수영 3.72 8↲ 이나라4.43 1↲ 김해수 3.77 6↲ 나태희 2.31↲ 유현빈 4.23↲ 나원빈4.42↲ 문건영 3.72↲ 소지법3.74↲ 나보내3.85↲ 장도건 4.06↲ 고수영 3.72↲ 이나라4.43↲ 김해수 3.77↲ [프로그램 4-4]
학생 평점 파일을 읽어 평점 순위 파일 만들기 • 분석 • 학생의 정보 • 구조체(이름, 평점 저장) • 학생의 수는 10명임을 알고 있는 경우임 • students.txt 파일 • 메모장에서 직접 만들어 프로젝트 폴더 안에 저장 • 모든 학생의 평점 정보가 있어야만 순위를 구할 수 있음→ 파일에서 읽은 정보를 모두 배열에 저장해야 함→ 파일의 내용을 읽어서 구조체 배열 s에 저장 • 순위 구하기 • 나의 평점 s[i].GPA보다 높은 평점의 개수가 n개 → 나의 순위 s[i].rank는 n+1등
4 – 4 : 성적 처리 프로그램 1 #include <stdio.h> // fopen, fscanf, fprintf, fclose, EOF, printf의 헤더 파일 2 #include <stdlib.h> // exit 함수를 위한 헤더 파일 3 #define SIZE 10 // 파일에 저장된 학생의 수 5 struct student // 구조체 정의 6 { 7 char name[20]; // 이름 8 double GPA; // 평점 9 int rank; // 순위 10 }; 11 12 int main() 13 { 14 struct student s[SIZE]; // 구조체 배열 선언 15 inti, u; 16 FILE *fp; // 파일 포인터 선언 17 18 fp = fopen("students.txt", "r"); // 학생 정보를 읽을 파일 열기 19 if (fp == NULL) // 파일 열기 에러 처리 20 { 21 printf("\n파일 열기 에러! \n"); exit(1); 22 }
4 – 4 : 성적 처리 프로그램 24 // 파일에 있는 학생 정보를 읽어 구조체 배열에 저장하기 25 for (i=0; i<SIZE; i++) 26 { 27 fscanf(fp, "%s %lf", s[i].name, &s[i].GPA); 28 } 29 fclose(fp); // 파일의 모든 자료를 배열에 저장했으므로 읽기용 파일을 닫기 30 31 // 파일에서 읽은 평점을 이용하여 나 s[i]의 순위를 구하기 32 for (i=0; i<SIZE; i++) 33 { 34 s[i].rank = 1; // 일단 나(i)의 순위를 1로 초기화 35 for (u=1; u<SIZE; u++) 36 { 37 // 나(i)의 평점이 다른 학생(u)의 평점보다 낮으면 순위를 1 증가 38 if (s[i].GPA < s[u].GPA) 39 s[i].rank ++; 40 } 41 }
4 – 4 : 성적 처리 프로그램 43 // 파일에 결과 출력하기 44 fp = fopen("rank.txt", "w");// 결과를 출력할 rank.txt 파일을 쓰기용으로 열기 45 if (fp == NULL) // 파일 열기 에러 처리 46 { 47 printf("\n파일 열기 에러! \n"); exit(1); 48 } 50 // SIZE명의 이름, 평점, 순위를 파일에 쓰기 51 for (i=0; i<SIZE; i++) 52 { 53 fprintf(fp,"%-8s %4.2lf %2d\n",s[i].name,s[i].GPA,s[i].rank); 54 // printf("%-8s %4.2lf %2d\n", s[i].name, s[i].GPA, s[i].rank); 55 } 56 fclose(fp); // 파일 닫기 57 printf("파일 출력 완료! \n"); 58 59 return 0; 60 }
파일의 끝 확인하기 • 파일에 저장된 레코드(데이터) 수를 정확히 모른다면? • 파일의 끝을 확인하여 파일 읽기를 중단하는 방법을 사용해야 한다. • 대표적 방법 두 가지 • feof함수 이용하기 • 파일의 끝을 지나 제대로 읽기를 못했다면 파일에서 읽기를 그만하기 • fscanf함수의 반환값 활용하기 • 파일의 끝에 도착하거나 에러가 발생하여 EOF를 반환하지 않았다면 읽은 데이터를 사용하고 그렇지 않다면 읽기를 그만하기
파일의 끝 확인하기 • feof함수 feof(파일포인터명) • 파일포인터에 연결된 파일의 끝을 지나갔다면 0이 아닌 값(참)을, 아직 파일의 끝을 지나지 않았다면 0(거짓)을 반환 • ㈜ 필독 파일의 끝(문자)에 도달했을 때가 아니라 파일 끝(문자)을 지나갔을 때 0이 아닌 값(참)을 반환함 → 제대로 이해하지 못했다면 [프로그램 12-5]와 같이 잘못된 결과를 초래할 수 있으므로 주의해야 한다. • 예) fp에 연결된 파일의 끝을 지났다면 파일을 닫기 if (feof(fp)) fclose(fp);
파일의 끝 확인하기 • [프로그램 4-5] • 문제 • 입력: [프로그램 4-3]의 결과 파일인 age.txt • 출력: age.txt 파일에저장된 모든 나이를 모니터에 표시하기 • 분석 • 프로그램 실행 결과로 만들어진 파일에 저장된 데이터 수는 파일을 확인하지 않는 한 알 수 없다. → feof함수를 이용하여 파일 끝을 지나지 않은 한 읽기를 계속하여 해결
4 - 5 : 파일의 끝을 확인하는 feof 함수의 정확한 사용 예 1 #include <stdio.h> // fopen, fscanf, fclose, feof 함수를 위한 헤더 파일 2 #include <stdlib.h> // exit 함수를 위한 헤더 파일 4 int main() 5 { 6 FILE *fp; // 파일 포인터 선언 7 int age; 8 9 fp = fopen("age.txt", "r"); // 파일을 읽기 모드로 열기 : 15 // 파일에 저장된 모든 나이를 읽어서 모니터에 출력하기 16 fscanf(fp, "%d", &age); // 일단 파일에서 정수(나이) 읽기를 시도 17 while (!feof(fp)) // 아직 파일의 끝을 지나지 않았다면 반복하기 18 { 19 printf("%2d \n", age); // 방금 파일에서 읽은 정수(나이)를 모니터로 출력하기 20 fscanf(fp, "%d", &age); // 파일에서 다음 정수(나이) 읽기를 시도 21 } 22 23 fclose(fp); // fp에 연결된 파일 닫기 25 return 0; 26 } • age.txt 파일의 내용 20↲ 23↲ 25↲
파일의 끝 확인하기 • fscanf 함수의 반환값 활용하기 • fscanf는 파일의 끝에 도착하거나 에러가 나면 EOF를 반환한다. → 일단 파일에서 읽기를 시도 후,fscanf의 반환 값을 확인하여 읽기의 성공 여부를 확인 가능 → 아주 단순하여 프로그래머들이 선호 // 일단 파일에서 정수를 한 개 읽어온 후 //성공했다면 출력하기를 반복하기 while (fscanf(fp, "%d", &age) != EOF) { printf("%2d\n",age); } • [프로그램 4-5] • : • 9 fp = fopen("age.txt", "r"); • : • 15 // 파일에 저장된 모든 나이를 읽어서 모니터에 출력하기 • 16 fscanf(fp, "%d", &age); • 17 while (!feof(fp)) • 18 { • 19 printf("%2d \n", age); • 20 fscanf(fp, "%d", &age); • 21 } • 22 • 23 fclose(fp); // fp에 연결된 파일 닫기 • age.txt 파일의 내용 20↲ 23↲ 25↲
판매실적 우수자 파일 만들기 • 문제: 판매실적 우수자 파일 만들기 • 입력: 사원 번호,자동차 판매 실적이 저장된 sales_report.txt파일 • 출력: 판매 실적이 30보다 큰 사원 번호,판매 실적을 저장한 good.txt파일 • 분석 • “sales_report.txt” 파일 만들기 자료를 읽을 순서에 맞게 자료형에 맞게 만들어야 하며마지막 자료 뒤에도 엔터키를 입력하는 것을 잊지 않는다. 판매실적 우수자 ------------ 사원번호 판매수 ------------ 1102 35대 1105 32대 1202 40대 1113 52대 ------------ • 1203 25↲ • 1102 35↲ • 1103 21↲ • 1205 29↲ • 1105 32↲ • 1202 40↲ • 1207 25↲ • 1112 27↲ • 1113 52↲ • 1212 27↲ sales_report.txt 파일 good.txt 파일 [프로그램 4-5]
4 – 6 : 사원 정보 파일에서 판매 실적 우수자 명단 파일 만들기 1 #include <stdio.h> // fopen, fscanf, fprintf, fclose, EOF, printf의 헤더 파일 2 #include <stdlib.h> // exit 함수를 위한 헤더 파일 3 4 int main() 5 { 6 int no, sales; 7 FILE *fpr, *fpw; // 읽기용, 쓰기용 파일 포인터 선언 8 9 fpr = fopen("sales_report.txt", "r"); // 판매 실적 파일을 읽기용으로 열기 10 if (fpr == NULL)// 파일 열기 에러 처리 11 {printf("파일 열기 에러! \n"); exit(1);} 14 15 fpw = fopen("good.txt", "w"); // 우수자 명단 파일을 쓰기용으로 열기 16 if (fpw == NULL) // 파일 열기 에러 처리 17 {printf("파일 열기 에러! \n"); exit(1);} 20 21 // 출력 제목을 파일에 쓰기 22 fprintf(fpw, "판매실적 우수자 \n\n"); 23 fprintf(fpw, " ------------------- \n"); 24 fprintf(fpw, " 사원번호 판매수 \n"); 25 fprintf(fpw, " ------------------- \n");
4 – 6 : 사원 정보 파일에서 판매 실적 우수자 명단 파일 만들기 27 // 파일에서 읽기를 성공했다면 판매수가 30보다 클 때만 우수자 명단 파일에 저장하기 28 while (fscanf(fpr, "%d %d", &no, &sales) != EOF) 29 { 30 if (sales > 30) 31 { 32 fprintf(fpw, " %5d %5d대 \n", no, sales); 33 // printf(" %5d %5d대 \n", no, sales); 모니터 결과 확인용 34 } 35 } 36 fprintf(fpw, " ------------------- \n"); 37 38 fclose(fpr); fclose(fpw); // 파일 닫기 39 printf(" 우수자 명단 파일을 저장했습니다. \n"); 40 41 return 0; 42 } 파일에 저장된 레코드 수를 모를 때 파일 읽기가 제대로 되었을 때만 while 본체 실행하기 good.txt 파일 sales_report.txt 판매실적 우수자 ------------- 사원번호 판매수 ------------- 1102 35대 1203 25 1102 35 1103 21 1205 29 1105 32 1202 40 : : fpr no 1102 sales 35
4 – 6 : 사원 정보 파일에서 판매 실적 우수자 명단 파일 만들기 good.txt 파일의 내용 sales_report.txt 파일의 내용 판매실적 우수자 -------------- 사원번호 판매수 -------------- 1102 35대 1105 32대 1202 40대 1113 52대 -------------- 1203 25 1102 35 1103 21 1205 29 1105 32 1202 40 1207 25 1112 27 1113 52 1212 27 [프로그램 12-13]
판매 실적 우수자 명단 파일 만들기 • 만일 판매실적을 내림차순으로 정렬하여 모니터로 출력하려면? • 정렬을 하기 위해서는 모든 자료가 배열에 저장되어야 하므로 파일에서 읽은 자료를 다음 그림과 같이 배열에 저장해야 한다. sales_report.txt 파일의 내용 1203 25 1102 35 1103 21 1205 29 1105 32 1202 40 1207 25 1112 27 1113 52 1212 27 배열을 정렬 후 모니터로 출력하기(printf) 또는 파일로 출력하기(fprinf)
파일 처리의 팁 • 파일 처리의 팁 • 파일로 출력하는 fprintf부분을 39행 처럼 모두 printf 함수로 작성한 후 • 결과가 제대로 나오면 36행 처럼 fprintf함수로 바꾸는 것도 결과를 쉽게 확하는 방법 예) 32행을printf(" %5d %5d대 \n", no, sales); 로 작성 후 fprintf(fpw, " %5d %5d대 \n", no, sales);로 수정하기 • 모니터와 파일 출력을 둘 다 하기 printf 함수로 출력하는 부분을 모두 복사하여 fprintf로 변경함으로써 모니터로도 결과를 출력하고 파일로도 출력 가능 32fprintf(fpw, " %5d %5d대 \n", no, sales); 33 printf(" %5d %5d대 \n", no, sales);
문자 단위로 파일에 쓰기 : fputc함수 • Text file 입출력 함수
문자 단위로 파일에 쓰기 : fputc함수 • fputc 함수 • 파일에 한 문자씩 출력 • 형식 • fputc(문자, 파일포인터명) → 문자를 파일포인터가 가리키는 파일에 씀 • fputc(정수, 파일포인터변수명) → ASCII 코드 값이 정수에 해당하는 문자 한 개를 파일에 씀 • 예 • fputc(67, fp); → fp에 연결된 파일에 'C'를 쓴다. • ch = 'A';fputc(ch, fp); →fp에 연결된 파일에 'A'를 쓴다.
문자 단위로 파일에 쓰기 : fputc함수 • fputc함수 • 파일에 한 문자씩 출력