티스토리 뷰

Programming/C, C++

malloc for student data

곰국 Gomsoup 2016.06.12 22:35

이번 학기 C++ 강좌의 Week 2 Assignment. Array 형태(ex : char temp[20];)를 사용하지 않고 따로 주어지는 data file에서 학생 정보를 찾아 학생 이름의 알파벳순으로 정렬하여 출력하는 과제였다. 


소스는 다음과 같음


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <stdio.h>
#include <stdlib.h>
 
#define BUF_SIZE 50
 
int sAlloc=0;
 
typedef struct stu{
    char *name;
    int score;
    int grade;
}student;
 
 
int lenName(char *name){
    int cnt;
 
    for(cnt = 0; ;cnt++){
        if*(name+cnt) == '\0' ) break;
    }
 
    return cnt;
}
 
void allocStud(student *s, char *name, int score, int grade){
    int i;
    (s+sAlloc)->name = (char *malloc(sizeof(char* lenName(name));
    
    for(i = 0; i<lenName(name); i++){
        *((s+sAlloc)->name + i) = *(name+i);
    }
 
    (s+sAlloc)->score = score;
    (s+sAlloc)->grade = grade;
 
    sAlloc++;
}
 
 
int inputScore(student **s){
    FILE *fp;
    int i;
 
    char *buf_name = (char *malloc(sizeof(char* BUF_SIZE);
    int buf_grade, buf_score;
 
    fp = fopen("data.txt""r");
 
    for(i = 0; ; i++){
        if(sAlloc == 0){
            if(fscanf(fp, "%s %d %d", buf_name, &buf_score, &buf_grade) == EOF) break;
            
            *= (student *malloc(sizeof(student));
            allocStud(*s, buf_name, buf_score, buf_grade);
        }
        
        else{
            if(fscanf(fp, "%s %d %d", buf_name, &buf_score, &buf_grade) == EOF) break;
            
            *= (student *)realloc(*s, sizeof(student) * (sAlloc+1));
            allocStud(*s, buf_name, buf_score, buf_grade);
        }
    }
    
    return i;
}
 
void printStu(student *s){
    int i;
 
    for(i=0; i<sAlloc; i++){
        printf("name : %s\nscore : %d\ngrade : %d\n\n\n\n", (s+i)->name, (s+i)->score, (s+i)->grade);
    }
}
 
void sortStu(student *s){
    int i, j;
    
    for(i=0; i<sAlloc-1; i++){
        for(j=i; j<sAlloc-1; j++){
            if(strcmp((s+i)->name, (s+j)->name) > 0)
                swapStu((s+i), (s+j));
        }
    }
}
 
void swapStu(student *s, student *t){
    student *temp = (student *)malloc(sizeof(student));
    
    *temp = *s;
    *= *t;
    *= *temp;
}
 
int main(){
    student *s;
 
    inputScore(&s);
    printStu(s);
    
    sortStu(s);
    printStu(s);
 
    return 0;
}
cs


int lenName(char *name);


- strlen의 역할. 따로 구현해보고싶어서 구현해봄



void allocStud(student *s, char *name, int score, int grade);


- main에서 주어진 student에 데이터를 입력해주는 역할. 이때 배열형태를 못써서 현재 얼마나 할당되어 있는지는 global로 sAlloc을 선언하여 구함.



int inputScore(student **s)


- 주어진 datafile에서 직접 데이터를 읽어오는 역할. 약간 고민을 했던게 버퍼 변수를 선언해야 하는가 였는데 결국 EOF를 활용하기 위해서는 선언해야 되더라. 또 student ** 으로 데이터를 받아온 이유 또한 malloc을 해주기 위함. 처음에 student *으로 받았다가 main으로 할당된 정보가 제대로 돌아가지 않아 구글링. 항상 함수 안에서 동적 할당을 해야하는 경우는 더블 포인터를 써주어 reference로 호출해 주어야함. 이유는 힙이 어쩌구 하던데 자세한건 방학때 알아보고 포스팅 하기로.



void printStu(student *s)


- 말 그대로 출력용



void sortStu(student *s)


- strcmp를 이용하여 student struct 내부 모든 이름을 비교함. 이 때 strcmp(a ,b) > 0라면 알파벳순으로 b가 더 작은 경우라고. 따라서 swapStu로 넘겨줌. 생각해보니 과제 검사 맡을 때는 qsort를 이용했었던것 같음. 따로 구현해봐야겠음.



void swapStu(student *s, student *t)


- 스왑용 



기억해야할 점

-C에서 배열은 포인터다. 단지 힙에 할당이 되어있느냐 없느냐의 차이. 하지만 포인터로 선언된 변수의 번지를 임의로 접근하는 것 (ex : char *s, printf("%s", s+1))은 overflow 발생 가능성을 높이므로 항상 배열 형태로 사용할 것!


'Programming > C, C++' 카테고리의 다른 글

malloc for student data  (0) 2016.06.12
댓글
댓글쓰기 폼
공지사항
최근에 달린 댓글
Total
3,325
Today
11
Yesterday
3
링크
TAG
more
«   2018/02   »
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28      
글 보관함