C++ 파일입출력 fgets

글쓴이: 익명 사용자 / 작성시간: 토, 2017/12/02 - 8:33오후
#include "stdafx.h" #include <iostream> #include <time.h> #include <stdlib.h> using namespace std; const int black = 0; const int red = 1; const int N = 10000; struct node { int b; char *key; struct node *l, *r; node(int bb, char *k, struct node*ll, struct node *rr) { b = bb; key = k; l = ll; r = rr; }; }; struct node *head, *z, *gg, *g, *p, *x; void split(char *insert_key); struct node *rotate(char *insert_key, struct node *y); class Dict { public: Dict() // 생성자: z와 head 초기화 { z = new node(black, 0, 0, 0); z->l = z; z->r = z; head = new node(black, 0, 0, z); } char* search(char *search_key); void insert(char *v); }; char* Dict::search(char *search_key) { struct node *x = head->r; // 첫번째 노드를 가리킴 while (x != z) // 비어있는 노드를 만날때까지 { if (x->key == search_key) // 현재 노드와 탐색 키가 같으면 return x->key; // 현재 노드 반환 // 현재 키 값보다 탐색 키 값이 작으면 현재 포인터 왼쪽으로, 크면 오른쪽으로 이동 x = (x->key > search_key) ? x->l : x->r; } return "doesn't exist"; // 탐색 키가 없으면 -1 반환 } void Dict::insert(char *v) { x = head; p = head; g = head; while (x != z) // 비어있는 노드를 만날때까지 { gg = g; g = p; p = x; if ((x->key) && (!strcmp(x->key, v))) // 만약 삽입할 키가 이미 존재한다면 종료 return; // 만약 삽입할 키가 현재 키보다 작다면 왼쪽으로, 크면 오른쪽으로 이동 if (x->key) x = (strcmp(x->key, v) == 1) ? x->l : x->r; else x = x->r; // 만약 왼쪽과 오른쪽 노드 색이 빨간색이라면 분할 if (x->l->b && x->r->b) split(v); } x = new node(red, v, z, z); // 새로운 노드 생성 if (p->key == NULL) p->r = x; // 최초의 노드일 경우 헤드의 오른쪽에 삽입 else if (strcmp(p->key, v) == 1) p->l = x; // 맨 오른쪽 노드보다 삽입 키 값이 작으면 삽입 키를 왼쪽에 삽입 else p->r = x; // 맨 오른쪽 노드보다 삽입 키 값이 크면 삽입 키를 오른쪽에 삽입 printf("%s", v); split(v); head->r->b = black; } void split(char *v) { x->b = red; // 만약 왼쪽과 오른쪽 노드 색이 빨간색이라면 분할 x->l->b = black; x->r->b = black; if (p->b) // 맨 오른쪽 노드가 빨간색이라면 { g->b = red; if ( (strcmp(g->key, v) == 1) != (strcmp(p->key, v) == 1) ) // 빨간색 꺾인 노드 회전 p = rotate(v, g); x = rotate(v, gg); // 빨간색 일자 노드 회전 x->b = black; } } struct node *rotate(char *v, struct node *y) { struct node *gc, *c; c = (strcmp(y->key, v) == 1) ? y->l : y->r; if (strcmp(c->key, v) == 1) { gc = c->l; c->l = gc->r; gc->r = c; } else { gc = c->r; c->r = gc->l; gc->l = c; } if (strcmp(y->key, v) == 1) y->l = gc; else y->r = gc; return gc; } int main() { Dict d; // 객체 생성 double start_time; char *insert_key, *search_key, *result; // 문자열 포인터 insert_key = (char *)malloc(5 * sizeof(char)); // char 5개 크기만큼 동적 메모리 할당 search_key = (char *)malloc(5 * sizeof(char)); result = (char *)malloc(5 * sizeof(char)); FILE *fp1 = fopen("dict.txt", "r"); // 읽기 전용으로 키 값 불러옴 FILE *fp2 = fopen("search_key.txt", "r"); if (fp1 == NULL || fp2 == NULL) { cout << "파일 open 실패." << endl; return 0; } start_time = clock(); while (!feof(fp1)) { fgets(insert_key, 6, fp1); d.insert(insert_key); // key를 트리에 삽입 } cout << "레드-블랙 트리의 삽입 시간: " << clock() - start_time << endl; start_time = clock(); while (!feof(fp2)) { fgets(search_key, 6, fp2); // 5 문자씩 불러와서 search_key에 저장 strcpy(result, d.search(search_key)); // search_key 탐색 if (strcmp(result, search_key)) // 탐색 키가 없거나 잘못된 값을 찾으면 { cout << "탐색 오류: " << search_key; // 오류 출력 return 0; } } cout << "레드-블랙 트리의 탐색 시간: " << clock() - start_time << endl; fclose(fp1); fclose(fp2); return 0; }
main의 첫번째 while문 속 fgets에 대한 질문입니다.
디버깅으로 확인해본 결과
첫 루프를 수행하면 첫번째 insert_key가 head->r에 들어가고,
두번째 루프에서 fgets만 수행하고 insert는 하기 전인데도 불구하고 inserted_key가
head->r에 덮어씌워져 첫번째 insert_key가 사라집니다...
아무리 고민하고 디버깅을 해봐도 왜 그런지 이유를 알 수가 없습니다..
txt파일도 함께 첨부합니다. 제발 고수님들 도와주세요..ㅜㅠㅠㅠ
File attachments:
첨부 | 파일 크기 |
---|---|
![]() | 2.18 MB |
![]() | 2.18 MB |
Forums:
지극히 당연한 현상입니다.
지극히 당연한 현상입니다.
Dict 자료구조 안의 key가 insert_key와 똑같은 포인터가 되잖아요. 즉 같은 메모리를 가리킨다는 말이지요.
insert_key가 가리키는 문자열을 바꿔도 자료구조 안의 값은 그대로 유지되기를 바란다면, 사본을 만들어 저장해야지요.
답변 감사합니다.
그럼 트리의 사본을 만들어야한다는건가요..?
댓글 달기