3. linked list
-
Upload
geunhyung-kim -
Category
Engineering
-
view
500 -
download
0
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)로�변환
파일�포인터