300 likes | 472 Views
학습 내용. 구조체 구조체 정의 및 선언 구조체 포인터 및 실습 공용체 파일 입출력 1 파일입출력 개념 관련 함수 실습 문제. 구조체 (structure) 개념. 실제 활용 가능한 프로그램 ( 도서관리 , 학사 관리 등의 업무용 프로그램 등 ) 에서 어떤 개체 ( 도서 , 학생 등 ) 을 표현할 때 , 정수 , 실수 형처럼 하나의 단순 데이터 형으로 표현할 수 있는 경우는 거의 없다 .
E N D
학습 내용 • 구조체 • 구조체 정의 및 선언 • 구조체 포인터 및 실습 • 공용체 • 파일 입출력 1 • 파일입출력 개념 • 관련 함수 • 실습 문제
구조체(structure) 개념 • 실제 활용 가능한 프로그램(도서관리, 학사 관리 등의 업무용 프로그램 등)에서 어떤 개체(도서, 학생 등)을 표현할 때, 정수, 실수 형처럼 하나의 단순 데이터 형으로 표현할 수 있는 경우는 거의 없다. • 예를 들어 학사 업무 프로그램에서 학생이라는 개체는 학번, 이름, 주소, 전화번호, Email주소 등의 여러 원소(속성)을 가지게 된다 • C 언어에서는 구조체를 이용하여 여러 원소를 가지는 새로운 자료구조체를 정의하고, 이 자료구조체 형태의 데이터(변수)를 선언하고, 사용할 수 있다. • 구조체는 두 개 이상의 원소를 가지는 복합 자료체이다. 이때 각 원소는 자신의 형(int char, , ..)을 따로 가지게 된다.
구조체 정의 및 선언 • 구조체 형식 정의 struct tag-name { type element1; type element2: …. } variable-list; • 예) 하나의 서적을 구조체 형으로 정의 struct book_type { char author[40]; /* 저자 이름 */ char title[40]; /* 책 제목 */ char pub[40]; /* 출판사명 */ unsigned date; /* 출판년도 */ int editon; /* 판 번호 */ } book1; • 새로운 데이터 형 book_type을 정의함. • book1은 book_type 형의 변수
구조체 정의 및 선언(계속) • book_type 형태로 새로운 변수가 book2, book3를 선언할 경우에는 다음과 같이 선언하면 된다. struct book_type book2, book3; struct book_type { char author[40]; char title[40]; char pub[40]; unsigned date; int editon; }; struct book_type book1; struct book_type { char author[40]; char title[40]; char pub[40]; unsigned date; int editon; } book1; ==
구조체 변수의 사용 • 구조체 변수의 각 원소를 사용하기 위해서는 . (dot 연산자)를 사용한다. -> 구조체변수.원소명 • 예 • book1.date = 1998; • printf(“Publication date : %u”, book1.date); • gets(book1.name); • scanf(“%d”, &book1.edtion)
#include <stdio.h> struct student { long num; int kor; int math; int eng; }; int main(void) { struct student st; printf("\n Input Student num : "); scanf("%ld",&st.num); printf(" Input Korean test result : "); scanf("%d",&st.kor); printf(" Input Mathmatics test result : "); scanf("%d",&st.math); printf(" Input English test result : "); scanf("%d",&st.eng); printf("\n * Student Info *"); printf("\n st.num %ld",st.num); printf("\n st.kor %d",st.kor); printf("\n st.math %d",st.math); printf("\n st.eng %d",st.eng); return 0; }
구조체 예제 1 • 학생 3명의 학번과 국영수 성적을 입력받아 국영수 성적합계가 가장 높은 학생의 학번과 성적합계를 출력하는 프로그램을 작성하시요. • 프로그램 처리 조건 • 학생 구조체 정의는 앞의 예제에 총합 필드를 추가하여 처리할 것. • 학생이 3명이므로 이를 구조체 배열(크기3)로 선언하여 처리할 것
#include <stdio.h> struct student { char name[15]; long num; /* student number */ int kor; int math; int eng; int total; }; int main(void) { struct student st[3]; int i, max; for(i=0; i<3; i++) { printf("\n Input Student name : "); scanf("%s",st[i].name); printf("\n Input Student num : "); scanf("%ld",&st[i].num); printf(" Input Korean test result : "); scanf("%d",&st[i].kor); printf(" Input Mathmatics test result : "); scanf("%d",&st[i].math); printf(" Input English test result : "); scanf("%d",&st[i].eng); st[i].total=st[i].kor+st[i].math+st[i].eng;
if(i==0) max=i; else { if(st[max].total<st[i].total) max=i; } } printf("\n * Best Score *"); printf("\n Student name : %s",st[max].name); printf("\n Student num : %ld",st[max].num); printf("\n Total Score : %d",st[max].total); return 0; }
구조체 포인터 • 예 struct s_type { int i; char str[50]; }s, *p; /* s는 s_type 형 변수, p는 구조체 포인터 */ p=&s; • -> 연산자 • 구조체 포인터가 가르키는 구조체의 원소를 지정하기 위해 사용된다. • 위의 예에서 p->i, p->str 등으로 접근이 가능하다. • 결국 p->i의 의미는 (*p).i와 같다,
실습 문제 • 학생 3명의 학번과 국영수 성적을 입력받아 국영수 성적합계가 가장 높은 학생의 학번과 성적합계를 출력하는 프로그램을 작성하시요. • 프로그램 처리 조건 • 학생 구조체 정의는 앞의 예제에 총합 필드를 추가하여 처리할 것. • 학생이 3명이므로 이를 구조체 배열(크기3)로 선언하여 처리할 것 • 학생 구조체의 포인터를 인수로 받아 국영수 성적을 합산해주는 기능을 가진 사용자 정의 함수를 사용하시오.
#include <stdio.h> struct student { char name[15]; long num; /* student number */ int kor; int math; int eng; int total; }; int st_total(struct student *); int main(void) { struct student st[3]; int i, max; for(i=0; i<3; i++) { printf("\n Input Student name : "); scanf("%s",st[i].name); printf("\n Input Student num : "); scanf("%ld",&st[i].num); printf(" Input Korean test result : "); scanf("%d",&st[i].kor); printf(" Input Mathmatics test result : "); scanf("%d",&st[i].math); printf(" Input English test result : "); scanf("%d",&st[i].eng); st[i].total=st_total(&st[i]);
if(i==0) max=i; else { if(st[max].total<st[i].total) max=i; } } printf("\n * Best Score *"); printf("\n Student name : %s",st[max].name); printf("\n Student num : %ld",st[max].num); printf("\n Total Score : %d",st[max].total); return 0; } int st_total(struct student *pst) { int sum; sum=pst->kor+pst->math+pst->eng; return sum; }
생각해보기 ? • 앞의 예제에서 학생 구조체 중 총합 필드외 평균 필드를 만들고, • st_total 함수에서 총합과 평균을 둘다 계산해서 리턴하도록 할 수 있을까? • 예를 들어 정수 두 개를 인수로 넘겨주면 두 수의 합과 차를 모두 리턴하는 함수를 구현할 수 있는 방법 은? • C 언어의 함수는 한가지 값만 리턴한다. 그러면 두가지 값을 같이 리턴하도록 할 수 있는 방법은?
/* 실습문제 2 앞의 소스를 변형하여 아래의 코드와 같이 함수 st_total_max 함수를 구현하시오. st_total_max 함수는 각 구조체 배열의 총점 계산 및 최고총점의 학생 인덱스를 검 색하는 기능을 함께 가지도록 한다. */ #include <stdio.h> struct student { char name[15]; long num; /* student number */ int kor; int math; int eng; int total; }; int st_total_max(struct student *, int); int main(void) { struct student st[3]; int i, max;
for(i=0; i<3; i++) { printf("\n Input Student name : "); scanf("%s",st[i].name); printf("\n Input Student num : "); scanf("%ld",&st[i].num); printf(" Input Korean test result : "); scanf("%d",&st[i].kor); printf(" Input Mathmatics test result : "); scanf("%d",&st[i].math); printf(" Input English test result : "); scanf("%d",&st[i].eng); } max = st_total_max(&st[0], 3); printf("\n * Best Score *"); printf("\n Student name : %s",st[max].name); printf("\n Student num : %ld",st[max].num); printf("\n Total Score : %d",st[max].total); return 0; } int st_total_max(struct student *pst, int count) { }
중첩 구조체 • 중첩 구조체 선언 예 struct std_type{ char name[10]; int num; char addr[40]; }; struct teacher_type { char name[10]; int class; struct std_type student[50]; } teacher1; • 사용 예 teacher1.student[0].num= 10;
구조체에서 비트 필드 사용 • 형식 Type name : size • 예 struct employee_type { unsigned num : 4; /* 0 – 15 */ unsigned married : 1; /* 0 or 1 */ unsigned depart : 3; } emp1;
공용체 • 여러 개의 원소들이 메모리의 같은 공간을 공유하게 하는 것. • 형식은 구조체와 흡사하며, 실제 공간의 구성 요소 중에 가장 큰 원소에 의해 결정된다. • 예 union u_type { int i; char c[2]; double d; } sample; • 실제 메모리 공간 d c[0] c[1] i
파일 입출력(표준 함수) • 입출력 데이터가 많고, 데이터를 저장할 필요가 있을 경우에 파일 입출력은 필수적인 프로그램 요소이다. • C 언어에서는 여러가지 입출력장치(디스크, 키보드, 모니터, 통신포트, 프린터) 등의 입출력을 위해 “스트림(stream)이라는 공통적인 접근 방법을 제공한다. • 스트림을 사용 절차 • 스트림을 오픈한다, • 입출력 작업을 수행 • 스트림을 닫는다(close) • 파일의 두가지 형태 • 텍스트(text) 모드 : 파일 내용을 문자로 취급하여 처리 • 이진(binary) 모드 : 파일 내용을 이진 데이터로 취급
파일 오픈 • fopen 함수 : 파일을 열어 스트림과 연결 • 형식 : FILE * fopen(char *fname, char *mode); • 선언 : <stdio.h> • 리턴값 : 파일포인터(성공) or 널 포인터(실패) • 인수 • fname : 오픈할 파일이름 • Mode r : 읽기 전용 텍스트 파일, w : 쓰기 전용 텍스트 파일, a : 추가전용 텍스트파일 rb : 읽기 전용 이진 파일, wb : 쓰기 전용 이진 파일, ab: 추가전용 이진파일 r+ : 읽고 쓰기 위한 텍스트 파일 오픈, w+ : 읽고 쓰기 위한 텍스트 파일 생성, a+ : 읽고 추가하기 위한 텍스트 파일 오픈 r+b : 읽고 쓰기 위한 이진 파일 오픈, w+b : 읽고 쓰기 위한 이진 파일 생성, a+b : 읽고 추가하기 위한 이진 파일 오픈
파일 닫기 • fclose 함수 • 형식 : int fclose(FILE *fp); • 선언 : <stdio.h> • 리턴 값 : 0(성공) or EOF(실패) • 파일 오픈,클로우즈 예제 FILE *fp; If ( (fp=fopen(“testfile.txt”,”r”) ==NULL ) { printf(“\n파일이 존재하지 않습니다.”); return(-1); } …. …. fclose(fp);
파일 입출력 함수(1) • fgetc : fp가 지정하는 파일에서 한 바이트를 읽어 정수형으로 반환한다. • 형식 : int fgetc(FILE *fp); • 선언 : <stdio.h> • 반환값 : 읽은 문자(성공) or EOF(실패) • fputc : fp가 지정한 파일에 인수 ch의 값을 쓴다. • 형식 : int fputc(int ch, FILE *fp); • 선언 : <stdio.h> • 반환값 : 쓴 문자(성공) or EOF(실패)
#include <stdio.h> int main(void) { FILE *fp; char ch; if((fp=fopen("test.txt", "r")) == NULL) { printf("\n File Open Error !!"); return(-1); } printf("\n\n ****** File Contents *****\n\n"); /* while((ch = fgetc(fp)) != EOF) putchar(ch); */ for(;;) { ch = fgetc(fp); if(ch==EOF) break; putchar(ch); } fclose(fp); getchar(); return 0; }
실습예제 1) 앞의 파일 입력 예제를 명령어 인수를 이용하여 유닉스의 cat 명령과 흡사하게 만드시오. • 즉 프로그램명을 read.exe로 하였다면, 리눅스 상에서 $ ./read test.txt 를 입력하면 test.txt 의 내용을 출력해주는 프로그램을 작성하시오. • 실습예제 2) 앞의 실습 예제를 다음과 같이 바꾸시오. • 파일 내용이 길어질 경우를 대비해서 파일 라인이 20라인 단위로 출력하도록 하시오.(20라인 출력하고 아무 키나 누르면다음 20라인이 출력하도록…)
/* 파일 복사 예제 */ #include <stdio.h> int main(void) { FILE *in, *out; char ch, rfname[20],wfname[20]; printf("\n Input Src File Name : "); gets(rfname); printf("\n Input Dst File Name : "); gets(wfname); if((in=fopen(rfname, "r")) == NULL) { printf("\n Src File Open Error !!"); return(-1); } if((out=fopen(wfname, "w")) == NULL) { printf("\n Dst File Open Error !!"); return(-1); } while((ch=fgetc(in)) != EOF) fputc(ch,out); fclose(in); fclose(out); return 0; }
파일 입출력 함수(2) • feof : 파일의 끝에 도달하였는지를 판별하는 함수 • 형식 : int feof(FILE *fp); • 선언 : <stdio.h> • 반환값 : 파일의 끝이면 0이 아닌 값, 끝이 아니면 다른 값 • 사용 예 FILE *fp; … … while(!feof(fp)) fgetc(fp);
파일 입출력 함수(3) • fgets : 파일의 문장을 str로 정의된 문자배열로 읽어들임. • 형식 : char * fgets(char *str, int num, FILE *fp); • 상세설명 : fp로 오픈된 파일에서 문자들을 str이 지정하는 문자열로 읽어오는데, num 개만큼 읽거나, 뉴라인 문자를 만나거나, 파일의 끝을 만날 때까지 수행함. • 선언 : <stdio.h> • 리턴값 : str(성공) or NULL(실패) • fputs : str이 지정한 문자열을 fp의 파일로 저장한다 • 형식 : int fputs(char *str, FILE *fp); • 선언 : <stdio.h> • 리턴값 : 양수 값(성공) or EOF(실패) • 표준입출력 장치명 • 파일포인터 대신 아래과 같이 지정된 표준 입출력 장치를 지명하여 표준 입출력 동작을 취할 수도 있다. • stdin(표준입력:키보드), stdout(표준출력:화면), stderr(표준에러출력:화면) • 예: fgets(buffer, sizeof(buffer), stdin);
#include <stdio.h> int main(int argc, char *argv[]) { FILE *out,*in; char str[256]; int i; if(argc != 2) { printf("\n Usage : filewrit file_name "); return (-1); } if((out=fopen(argv[1],"w")) == NULL) { printf("\n File Open Error !!"); return(-1); } printf("\n Enter . to stop\n"); for(i=1; 1; i++) { printf("%3d : ",i); gets(str); if(*str == '.') break; fputs(str, out); fputc('\n',out); } fclose(out); return 0; }
실습 예제 3) 파일 복사 예제 프로그램을 fputs와 fgets를 이용하여 작성하시오. • 실습 예제 4) 파일명과 문자열을 입력 받아, 그 파일에서 그 문자열이 있는 라인을 화면에 모두 출력하는 프로그램을 작성하시오.