3. linked list

Post on 21-Mar-2017

499 views 0 download

Transcript of 3. linked list

Linear List - Linked List -

Geun-Hyung Kim UMCL @ Dong-Eui University

리스트�(List)�개념

리스트�/�선형리스트�순서가�있는�항목의�모임�

기본�연산:��추가(add),�제거(delete),�검색(search)�등�

리스트를�구현하는�대표적인�방법:�배열,�연결리스트�

배열�구현이�간단하고�효율적임�-�배열의�인덱스�번호로�저장공간�접근�가능�

리스트의�크기가�고정�-�저장공간�재�할당이�필요�

리스트의�중간에�항목을�추가/삭제�시�다른�항목을�옮겨야�함�

연결리스트�리스트의�중간에�항목을�추가/삭제�시�다른�항목을�옮길�필요�없음��

링크�필드를�위한�추가�저장�공간이�필요�

리스트의�중간�항목을�바로�접근하는�것이�불가능��

배열과�연결�리스트

Tuesday

Friday

Wednesday

Monday

예)�이번주�약속�목록

배열

100

101

102

103

104

105

106

107

108

109

110

Tuesday

��

Monday

Wednesday

Friday

100

101

102

103

104

105

106

107

108

109

110

107

NULL

103

105

연결�리스트�(head:101)

배열�리스트의�추가�제거

Tuesday

Friday

WednesdayMonday

100

101

102

103

104

105

106

107

108

109

110

Tuesday

Friday

WednesdayMonday

100

101

102

103

104

105

106

107

108

109

110

add�‘Saturday’��on�2nd�position

Tuesday

Saturday

Friday

WednesdayMonday

100

101

102

103

104

105

106

107

108

109

110

delete�‘Friday’�

Tuesday

Saturday

WednesdayMonday

Tuesday

Saturday

Wednesday

Monday

Tuesday

Friday

Wednesday

Monday

Tuesday

Friday

WednesdayMonday

Tuesday

Friday

WednesdayMonday

Tuesday

Satursday

Friday

WednesdayMonday

Tuesday

Satursday

WednesdayMonday

연결�리스트의�추가�제거

Tuesday

Monday

Wednesday

Friday

100

101

102

103

104

105

106

107

108

109

110

107

NULL

103

105

연결�리스트�(head:101)

Tuesday

Monday

Wednesday

Friday

Saturday

100

101

102

103

104

105

106

107

108

109

110

108

NULL

103

105

107

Tuesday

Monday

Wednesday

Saturday

100

101

102

103

104

105

106

107

108

109

110

108

NULL

103

105

add�‘Saturday’�on�2nd�position

delete�‘Friday’

�노드�(node)

노드�(Node)

노드는�리스트를�연결�리스트로�구현할�때��리스트의�각�요소�(element)의�정보를�저장공간에�저장하는�단위�

각�노드는�실제�정보를�저장하는�데이터�필드와�다른�노드를�가리키는�링크�필드로�구성�

data

link

Tuesday

data

link

Saturday

data

link

Wednesday

data

link

Monday

NULL

head

연결리스트의�마지막�노드의�링크�필드는�NULL�값을�갖는다.

연결리스트의�첫�노드의�주소는�head�pointer에�별도로�저장하여야�한다.

연결리스트를�구성하는�노드의�링크�필드는�다음�노드의�주소를�가리킨다.

노드의�C�언어�구현

struct node { int data; struct node *link;}

데이터�필드�(정수�값�저장)

링크�필드��(sturct�node�자료형의��주소를�저장하는�변수)

노드�구조체�정의��(새로운�자료형�정의)

typedef struct node ListNode;ListNode *head;

struct�node��자료형을�ListNode�자료형으로�재�정의

head�포인터�변수�선언

동적�메모리�할당

typedef struct node { int data; struct node *link;} ListNode;

ListNode *p1;p1 = (ListNode *)malloc(sizeof(ListNode)):

구조체의�정의와�동시에��새로운�ListNode�자료형�정의

예제�프로그램

int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL;

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode;

newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30;newNode->link = NULL;

head = newNode;

ListNode *p = head; while(p!=NULL) {

printf(“%d\n”, p->data);p = p->link;

}}

NULL10head

int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL;

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode;

newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30;newNode->link = NULL;

head = newNode;

ListNode *p = head; while(p!=NULL) {

printf(“%d\n”, p->data);p = p->link;

}}

예제�프로그램

10head

NULL20newNode

int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL;

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode;

newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30;newNode->link = head;

head = newNode;

ListNode *p = head; while(p!=NULL) {

printf(“%d\n”, p->data);p = p->link;

}}

예제�프로그램

10head

NULL20newNode 30

int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL;

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode;

newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30;newNode->link = head;

head = newNode;

ListNode *p = head; while(p!=NULL) {

printf(“%d\n”, p->data);p = p->link;

}}

예제�프로그램

10

head

NULL20

p 30

30

1020

예제�프로그램

int main() { ListNode *head = (ListNode *)malloc(sizeof(ListNode)); head->data = 10; head->link = NULL;

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 20; newNode->link = NULL; head->link = newNode;

newNode = (ListNode *)malloc(sizeof(ListNode)); newNode->data = 30;newNode->link = NULL;

head = newNode;

ListNode *p = head; while(p != NULL) {

printf(“%d\n”, p->data);p = p->link;

}}

연결리스트�맨�앞에�노드�추가�하기

data

link

30

data

link

20

data

link

10

data

link

100

NULL

head

(1)새로운�노드를�만들고�데이터를�저장한다.

data

link

40

(2)�새로운�노드의�link�필드가�현재의�head�노드를�가리키도록�한다.

(3)�새로운�노드를��새로운�head�노드로�한다.

연결리스트�맨�앞에�노드�추가�하기

data

link

30

data

link

20

data

link

10

data

link

100

NULL

head

data

link

40

newNode = (ListNode *)malloc(sizeof(ListNode));newNode->data = 40;

head = newNode;

newNode->link = head;

연결리스트�맨�앞에�노드�추가�하기

함수�정의(구현�1)�반환�자료�형:�없음�함수�이름:�insertFirst�입력�파러미터(1):�저장할�정수�값�

void insertFirst(int item){

ListNode *node = (ListNode *) malloc(sizeof(ListNode));node->data = item;node->link = head;head = node;

}

Q)�head는�어디에�있나�?

모든�함수에서�직접�접근이�가능하도록�전역�변수로�선언되어�있음��

함수호출�예:�insertFirst(10);

연결리스트�맨�앞에�노드�추가�하기

반환�자료�형:�없음�함수�이름:�insertFirst�입력�파러미터(2):�저장할�정수�값,�첫�노드의�가리키는�head�포인터�변수의�주소

void insertFirst(ListNode **ptrHead, int item){

ListNode *node = (ListNode *) malloc(sizeof(ListNode));node->data = item;node->link = *ptrHead;*ptrHead = node;

}

함수호출�예: insertFirst(&head, 10);

첫�노드를�가리키는�head�포인터가�로컬��변수로�선언되어�있음

Q)�head의�정보를�전달할�때�**ptrHead를��사용하는�이유는�?

head�포인터의�값을�insertFirst()�함수�내에서�변경되어야�하고�함수�밖에서도�변경이�반영되어야�하기�때문에�head�포인터의�주소를�전달해야�하므로��

함수�정의(구현�2)�

연결리스트�맨�앞에�노드�추가�하기

반환�자료�형:�ListNode�자료를�가리키는�주소�값�함수�이름:�insertFirst�입력�파러미터(2):�저장할�정수�값,�첫�노드의�가리키는�head의�값

ListNode *insertFirst(ListNode *head, int item){

ListNode *node = (ListNode *) malloc(sizeof(ListNode));node->data = item;node->link = head;return node;

}

함수호출�예: head = insertFirst(head, 10);

함수�정의(구현�3)�

특정�노드�뒤에�새로운�노드�추가�하기

data

link

30

data

link

20

data

link

10

data

link

100

NULL

head

(1)새로운�노드를�만들고�데이터를�저장한다.

data

link

40

(2)�새로운�노드의�link�필드가��������현재의�head�노드를�가리키도록�한다.

(3)�새로운�노드를��prev의�다음�노드로�설정한다.

prev

특정�노드�뒤에�새로운�노드�추가�하기

data

link

30

data

link

20

data

link

10

data

link

100

NULL

head

data

link

40

prev

newNode = (ListNode *)malloc(sizeof(ListNode));newNode->data = 40;

prev->link = newNode;

newNode->link = prev->link;

특정�노드�뒤에�새로운�노드�추가�하기

특정�노드�뒤에�새로운�노드�추가�하기특정�노드�뒤에�새로운�노드�추가�하기

반환�자료�형:�없음�함수�이름:�insertAfterNode�입력�파러미터(2):�저장할�정수�값,�데이터를�저장할�위치�전�노드의�주소�값

void insertAfterNode(ListNode *prev, int item){

ListNode *node = (ListNode *) malloc(sizeof(ListNode));node->data = item;node->link = prev->link;prev->link = node;

}

함수�정의(구현)�

두가지�노드�추가�기능��통합�

반환�자료�형:�없음�함수�이름:�insertNode�입력�파러미터(3):�head�포인터�변수의�저장�주소,�저장할�위치�앞의�노드�주소,����������������������������새로운�노드의�주소

함수�정의(구현)�

void insertNode(ListNode** phead, ListNode* p, ListNode* newNode){ if(*phead == NULL){ //공백�리스트�� newNode->link = NULL; *phead = newNode; } else if(p == head){ //p가�NULL로�리스트의�첫번째�노드에�삽입 newNode->link = *phead;

*phead = newNode; } else{ //p 다음에�삽입� newNode->link = p->link; p->link = newNode; }}

연결리스트의�첫번째�노드�삭제

data

link

30

data

link

20

data

link

10

data

link

100

NULL

headhead�가�두번�째�노드를�가리키도록�함�

head = head->link;

연결리스트의�첫번째�노드�삭제

반환�자료�형:�삭제한�노드의�주소�함수�이름:�removeFirst�입력�파러미터(0):�없음�(head가�전역변수�일때)

ListNode *removeFirst(){

if (head == NULL) return NULL;else { ListNode *node = head->link; head = head->link; return node;}

}

함수�정의(구현�1)�

연결리스트의�첫번째�노드�삭제

반환�자료�형:�삭제한�노드의�주소�함수�이름:�removeFirst�입력�파러미터(1):�head�포인터의�주소�(head�가�로컬�변수�일때)

ListNode *removeFirst(ListNode **head){

if (*head == NULL) return NULL;else { ListNode *node = *head->link; *head = *head->link; return node;}

}

함수�정의(구현�2)�

특정�노드�뒤의�노드를�삭제�하기

data

link

30

data

link

20

data

link

10

data

link

100

NULL

headprev

prev�노드가��prev�노드가�가리키는�노드의��다음�노드를�가리키도록�한다�

반환�자료�형:�삭제한�노드의�주소�함수�이름:�removeAfter�입력�파러미터(2):�head�포인터�변수의�주소�(head�가�로컬�변수�일때),�데이터를�삭제할�노드의�전�노드�주소�값

함수�정의(구현)�

특정�노드�뒤의�노드를�삭제�하기

ListNode *removeAfter(ListNode **head, ListNode *prev){

ListNode *node = prev->link;if (*head == NULL) return NULL;else if (node == NULL) return NULL;

else { prev->link = node->link; return node;}

}

연결�리스트�순회하기

data

link

30

data

link

20

dat

lin

10

data

link

100

NULL

head

p

연결리스트�순회는�리스트의�모든�노드를�처음부터�순차적으로�방문하는�것을�뜻한다.�

각�노드가�다음�노드의�데이터가�저장된�주소�정보를�가지고�있으므로�이를�이용하여��

모든�노드를�순회할�수�있다.

연결리스트�순회하기

반환�자료�형:�없음�함수�이름:�traverse�입력�파러미터(1):�head�포인터�변수에�저장된�값

ListNode traverse(ListNode *head){

ListNode *p = head;while (p != NULL) { p = p->link;}

}

함수�정의(구현)�

연결리스트에서�원하는�값�탐색

반환�자료�형:��ListNode�자료형의�주소�함수�이름:�search�입력�파러미터(2):�head�포인터에�저장된�값,�탐색하려는�정수�값

ListNode *search(ListNode *head, int value){

ListNode *p = head;while (p != NULL) { if (p->data == value) return p; p = p->link;}return p;

}

함수�정의(구현)�

두�연결�리스트의�연결�

반환�자료�형:��ListNode�자료형의�주소�함수�이름:�concat�입력�파러미터(2):�첫�번째�연결리스트와�두번째�연결리스트의�head�값�

ListNode *concat(ListNode *head1, ListNode *head2){

ListNode *p;if(head1 == NULL) return head2;else if (head2 == NULL) return head1;else {p = head1;

while (p->link != NULL) { p = p->link; } p->link = head2; return head1;}

}

함수�정의(구현)�

연결리스트를�역순으로�만들기

data

link

30

data

link

20

data

link

10

data

link

100

NULL

head

qr알고리즘�고찰�1.�첫�노드의�link�값(r->link)�을�NULL�로�설정

NULL

2.�두번째�노드의�link�값(q->link)을�이전의�노드(r)로�설정

문제�발생:�다음�링크에�대한�정보가�없어짐��해결방안:�2의�link�값을�변경하기�전에�link�값�(p)�을�저장해�놓아야�함�

p

1-1.��두번째�노드(q)의�다음�노드를�저장�(p)�

3.�p,�q,�r을�모두�하나씩�오른쪽을�이동� r = q;q = p;p = p->link;q->link = r;

연결리스트를�역순으로�만들기

data

link

30

data

link

20

data

link

10

data

link

100

NULL

head

p

p=head;q=Null;

q

q=p;p=p->link;

r=q;

1. 초기 상태

q->link=r;

NULL

r

NULL

r=q;q=p;p=p->link;

q->link=r;

r=q;q=p;p=p->link;

q->link=r;

r=q;q=p;p=p->link;

q->link=r;

연결리스트를�역순으로�만들기

반환�자료�형:��ListNode�자료형의�주소�함수�이름:�reverse�입력�파러미터(1):�head�포인터에�저장된�값

ListNode *reverse(ListNode *head){

ListNode *p, *q, *r;q=NULL;p=head;while (p!=NULL){ r=q; q=p; p=p->link; q->link=r;}return q;

}

함수�정의(구현)�

새로운�노드를��새롭게�생성하는�함수

반환�자료�형:�동적으로�생성한�노드의�주소��함수�이름:�createNode�입력�파러미터(2):��저장할�데이터,�노드에�연결할�다른�노드�주소�

ListNode *createNode(int data, ListNode *link){

ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));if(newNode == NULL)error(“memory allocation error”);

newNode->data = data;newNode->link = link;return newNode;

}

함수�정의(구현)�

원형�연결�리스트�- Circular Linked List -

원형�연결�리스트�

data

link

30

data

link

20

data

link

10

data

link

100

head

원형�연결�리스트 마지막�노드가�첫�번째�노드를�가리키는�연결�리스트

data

link

30

data

link

20

data

link

10

data

link

100

head

원형�연결�리스트�처음에�노드�추가�

newNode->link = head->link;

head->link = newNode;

data

link

30

data

link

20

data

link

10

data

link

100

head

data

link

40

원형�연결�리스트�처음에�노드�추가�

반환�자료�형:�없음�함수�이름:�insertFirst2Circular�입력�파러미터(2):�head�포인터�변수의�주소,�새로운�노드�

void insertFirst2Circular(ListNode **phead, ListNode *newNode){

if (*phead == NULL){ // 공백 리스트 *phead = newNode; newNode->link = newNode;}else{ newNode->link = *phead->link; *phead->link = newNode;}

}

함수�정의(구현)�

원형�연결�리스트�마지막에�노드�추가

data

link

30

data

link

20

data

link

10

data

link

100

head

data

link

40

newNode->link = head->link;

head->link = newNode;

head = newNode;

원형�연결�리스트�마지막에�노드�추가

반환�자료�형:�없음�함수�이름:�insertLast2Circular�입력�파러미터(2):�head�포인터�변수의�주소,�새로운�노드�

void insertLast2Circular(ListNode **phead, ListNode *newNode){

if (*phead == NULL){ // 공백 리스트 *phead = newNode; newNode->link = newNode;}else{ newNode->link = *phead->link; *phead->link = newNode; *phead = newNode;}

}

함수�정의(구현)�

원형�연결�리스트�순회하기

data

link

30

data

link

20

data

link

10

data

link

100

head

p

순회�종료�조건p->link == head

ListNode traverse(ListNode *head){

ListNode *p = head;while (p->link != head) { p = p->link;}

}

연결리스트�응용��-�다항식�-

연결�리스트�응용:�다항식�표현

다항식 p(n)=anxn+an-1xn-1+…+a0

연결리스트를�이용하여�하나의�다항식을�표현하는�구조체�(Polynomial)를�정의�

다항식을�항들의�연결�리스트로�표현�

항�들은�차수의�내림차순으로�정렬하여�저장하고�동일�차수의�항은�2개�이상�가지지�않으며�계수가�0인�항은�존재하지�않음��

하나의�항은�계수와�지수로�표현하며�하나의�항도�구조체(Term)로�표현�

다항식�표현�예

coef

link

3

12

expo

A(x)=3x12+4x8+1

coef

link

4

8

expo

coef

link

1

0

NULL

expo

Term Term Term

name

size

A

3

first

Polynomial

구조체�Term

typedef struct Term {int coef;int expo;struct Term *link;

}Term;

구조체�Polynomial

typedef struct Polynomial {char name[20];Term *first;int size;

} Polynomial;

새로운�항목�생성하기

Term *createTerm(int coef, int expo) {Term *term = (Term *)malloc(sizeof(Term));term->coef = coef;term->expo = expo;term->link = NULL;return term;

}

Polynomial *createPolynomial(char* name) {Polynomial *poly = (Polynomial *)malloc(sizeof(Polynomial));strcpy(poly->name, name); term->size = 0;term->first = NULL;return poly;

}

다항식에�항목�추가하기

coef

link

3

12

expo

coef

link

4

8

expo

coef

link

1

0

NULL

expo

Term Term Term

name

size

A

3

first

Polynomial

addTermtoPloy(int c, int e, Polynomial *p);

다항식�p에�차수가�e이고�계수가�c인�항을�더하기

알고리즘�개요�추가하려는�항의�차수가�다항식에�있으면,�coef�값에�계수�값을�더함�

추가하려는�항의�차수가�다항식에�없으면,�Term을�생성후�값을�대입하고�올바른�위치에�추가

다항식에�항목�추가하기

coef

link

3

12

expo

coef

link

4

8

expo

coef

link

1

0

NULL

expo

Term Term Term

name

size

A

3

first

Polynomial

새로운�항이�추가되는�경우�:�6x10�을�추가하는�경우�

coef

link

6

10

NULL

expo

Term *cur = p->first, *prev = null;

cur

while(cur != NULL && cur->expo > e){prev = cur;cur = cur->link;

}

prev

prev->link = newTerm;newTerm->link =cur;

void addTermtoPoly(int c, int e, Polynomial *p) {if (c ==0 || p == NULL) return;Term *cur = p->first, *prev =NULL;while (cur != NULL && cur->expo > e) {prev = cur;cur = cur->link;

}if (cur != NULL && cur->expo == e) {cur->coef += c;if(cur->coef == 0) { if (prev == NULL) p->first = cur->link; else prev->link = cur->link; p->size--; free(cur);}return;

}Term *newTerm = createTerm(c, e);if (prev == NULL) p->first = newTerm;else { prev->link = newTerm; newTerm->link = cur;}p->size++;

}

다항식에�항목�추가하기�-구현

다항식�출력하기

void polyPrint(Polynomial *poly) {Term *ptrTerm = poly->first;for (int i = 0; i < poly->size; i++) {

printf("%dx^%d ", ptrTerm->coef, ptrTerm->expo); if (i != poly->size -1) printf(" + "); ptrTerm = ptrTerm->link; } printf("\n");}

다항식�삭제하기

void delPolynomial(Polynomial *poly) {Term *ptrTerm = poly->first, *cur;for (int i = 0; i < poly->size; i++) {cur = ptrTerm;

ptrTerm = ptrTerm->link; free(cur); } free(poly);}

�두�다항식�더하기다항식�더하기

Polynomial *addPoly(Polynomial *a, Polynomial *b) {

Term *pa = a->first, *pb = b->first, *newTerm; int coef, expo; Polynomial *result = createPolynomial(“sum”);

while (pa != NULL && pb != NULL) { if (pa->expo > pb->expo) { coef = pa->coef; expo = pa->expo; addTermtoPoly(coef, expo, result); pa = pa->link; } else if (pa->expo == pb->expo) { coef = pa->coef + pb->coef; expo = pa->expo; addTermtoPoly(coef, expo, result); pa = pa->link; pb = pb->link; } else { coef = pb->coef; expo = pb->expo; addTermtoPoly(coef, expo, result); pb = pb->link; } } while (pa != NULL){addTermtoPoly(pa->coef, pa->expo, result); pa = pa->link;} while (pb != NULL){addTermtoPoly(pb->coef, pb->expo, result); pb = pb->link;}

return result;}

Summary of Linked Lists

#ifndef _Linked_List_#define _Linked_List_

ListNode *createNode(int data, ListNode *link);void insertFirst(ListNode **ptrHead, int item);void insertAfterNode(ListNode *prev, int item);void insertNode(ListNode** phead, ListNode* p, ListNode* newNode);ListNode *removeFirst(ListNode **head);ListNode *removeAfter(ListNode **head, ListNode *prev);ListNode traverse(ListNode *head);ListNode *search(ListNode *head, int value);ListNode *concat(ListNode *head1, ListNode *head2);ListNode *reverse(ListNode *head);

#endif

Linked_List

Linked_List:�추가되어야�할�요소

int isEmpty(ListNode *ptrHead); // List가�비어�있는지�확인�int getLength(ListNode *ptrHead); // List의 Node 수�확인�// List에서 pos에�있는 Node를�반환��ListNode *getNodeAt(ListNode *ptrHead, int pos);// List에서�pos에�있는 data를�반환��int getEntryAt(ListNode *ptrHead, int pos);// List에서�주어진�위치에�데이터�삽입�void insertNodeAt(ListNode **ptrHead, int pos, int item);// List의�마지막에�데이터�삽입�void insertLast(ListNode **ptrHead, int item);// List에서�주어진�위치의�데이터를�삭제ListNode *removeAt(ListNode **ptrHead, int pos);// List의�모든�노드를�삭제�void removeAll(ListNode *ptrHead);// List의�모든�노드의�데이터�출력�void printData(ListNode *ptrHead);

�연결�리스트�응용�- line editor -

Line�Editor Editor�Command�창에서�한�줄씩�입력하거나�삭제�

라인�번호와�라인의�내용을�입력받아�지정된�위치에�저장�

각�라인에�해당하는�텍스트를�연결�리스트�노드의�데이터로�처리�

커서를�사용하지�않는�단순한�에디터�

파일을�이용하여�문서를�저장�및�편집

Line�Editor

파일�읽고�쓰기�위한�기본�함수��파일을�열고�닫는�함수:�fopen,�fclose�

파일로�부터�데이터를�읽는�함수:�fscanf,�fgets,�fread��

파일로�데이터를�쓰는�함수:�fprintf,�fputs

Line Editor: fopen/fclose

fopen() 함수�프로토타입: FILE* fopen(const char* filename, const char* mode);

FILE: _iobuf라는�구조체�(입출력장치에�대한�관련�정보�저장)

filename: 읽거나�쓰고자�하는�파일�이름mode (파일�액세스�모드): r, w, a, r+, w+, a+, t , b

fclose() 함수�프로토타입:

int fclose(File* fprt);

반환�데이터:�파일이�오류없이�닫히면�0을�리턴

fopen() 함수로�파일을�열었으면�작업을�완료�후�반드시 fclose()함수로�닫아야�함

입력�파라미터:�파일포인터

입력�파라미터:

반환�데이터:�파일�포인터

Line Editor / fgets()

fgets() 함수�프로토타입:�

char* fgets(char *string, int n, FILE* stream);

반환�데이터:�읽은�문자열의�포인터,�더�읽을�내용이�없거나�에러�시�NULL 반환

입력�파라미터(3):�파일�데이터를�읽어�저장할�버퍼의�포인터�(string), 읽을�최대�문자�수�+1 (n),

오픈한 FILE 구조체�(_iobuf 구조체) 포인터 (stream)

#include <stdio.h>int main(){ char buf[20]; char *line; FILE *fptr = fopen(“data.txt”,”r”); if(fptr == NULL) { // 에러�처리 } else { while ((line = fgets(buf, sizeof(buf), fptr)) != NULL) { printf(“%s”,line);

} fclose(fptr);}return 0;

}

파일에서�읽은�데이터�포인터

파일�끝이나�‘\n’�문자까지�읽음�라인�끝(CR/LF)을�읽으면�개행�문자�‘\n’으로�변환�읽은�문자들�끝에�NULL�문자�추가

오픈한�파일에서�문자열을�한�줄씩�읽어옴

Line Editor: fputs()

fputs() 함수�프로토타입: int fputs(const char *string, FILE* stream);반환�데이터:�성공�시�0�또는�양수,�실패�시 EOF(-1)

입력�파라미터(2):�파일에�쓸�NULL로 끝나는�문자열�버퍼의�포인터 (string), 오픈한�FILE 구조체�(_iobuf 구조체)�포인터 (stream)

개방된�파일에�문자열을�라인�단위로�저장

int main( ){ char buf[255]; FILE *fptr = fopen("data1.txt", "w"); int result; if(fptr == NULL) { // 에러�처리�코드�

} else { for (int i = 0; i < 5; i++ ) { sprintf(buf, "[line:%d] %s \n", i+1, in[i]); result = fputs(buf, fptr); if (result == -1) printf ("file write error\n"); } fclose(fptr); } }

쓰기�모드

파일에�저장될�문자�한�줄�

개행�문자�‘\n’�문자를�라인�끝(CR/LF)로�변환

파일�포인터