이전 코드 구조체 안 배열을 char *로 바꿔서 풀어보기.
동적할당을 이용한 문자열 처리
- 문자열을 입력받기 위한 충분한 크기의 문자 배열을 선언한다.
- 문자열을 입력 받는다.
- 입력된 문자열의 길이를 계산하여 그 크기에 맞게 기억공간을 동적으로 할당받는다.(널문자까지 포함한 메모리를 할당하기);
- 문자열을 복사한다.
관련 내용 조금 공부
문자열 포인터의 배열
2차원 배열 대신, 문자배열의 포인터를 이용해서 정리. 이는 문자열의 최대 길이로 각 요소의 길이가 고정되는 2차원 배열과는 달리, 개별 문자열의 시작 위치에 대한 포인터들의 배열이며, 따라서 사용되지 않고 남는 메모리가 없다.
동적으로 할당되는 배열 사용하기
-
기본적으로 “문자열 배열”은 char**타입으로 지정하고 문자열의 적정 개수 혹은 최소 개수에서 시작한다. 그리고 초기 상태에서 문자열을 저장하기 위한 메모리 공간은 전혀 할당하지 않은 상태로 시작한다.
-
문자열 배열에 새로운 문자열을 삽입하려면, 삽입하고자 하는 문자열을 저장할 메모리 공간을 동적으로 할당하고, 이 영역으로 문자열을 복사한다. 그리고 문자열 배열의 i번재 칸의 값은 새롭게 할당할 지점의 포인터를 저장한다.
-
이와 같은 방식으로 배열을 다루면, 배열 자체는 문자열 포인터를 저장하는 연속적인 구간이 된다. 그리고 각 포인터가 가리키는 곳은 별도로 할당된 메모리 영역이며, 이 경우 문자열을 사용하는 것에 대해서는 실제 2차원 배열 혹은 연속적인 문자열 영역과는 아무런 차이가 없을 수 있다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF 255
typedef struct Student {
char *name;
int kor, eng, math, sum, rank;
}ST;
//버퍼에 우선 입력을 받고 그 크기만큼
//동적할당하여
//name에 strcpy를 해준다.
int input(const char * msg);
void setData(ST * pt, int su);
void setRank(ST * pt, int su);
void disp(ST *pt, int su);
int main(void) {
int su = input("학생 수");
ST * pt = (ST *)malloc(sizeof(ST)*su);
setData(pt, su);
disp(pt, su);
//name영역 해제
for(int i = 0; i < su; i++){
free(pt[i].name);
}
free(pt);
return 0;
}
int input(const char *msg) {
int su;
printf("%s 입력 : ", msg);
scanf("%d", &su);
getchar(); // getchar를 여기에 써주는게 좋다.swtichcase문으로 만든다고 가정해보자.
return su;
}
void setData(ST* pt, int su) {
printf("\\\\정보 입력 \\\\\n");
//초기 할당할 버퍼가 필요하다.
char Buffer[BUF]; // 초기화
for (int i = 0; i < su; i++) {
printf("%d번째 학생 정보 \n", i+1);
printf("이름 입력 : ");
//scanf_s("%s", pt[i].name,sizeof(pt[i].name));
//gets(pt[i].name);
gets(Buffer);//문자열 입력;
pt[i].name = (char *)malloc(strlen(Buffer)+1); //null문자까지 계산
strcpy(pt[i].name,Buffer); //strcpy(A,B) B를 A로 복사
pt[i].kor = input("국어 점수");
pt[i].eng = input("영어 점수");
pt[i].math = input("수학 점수");
pt[i].sum = pt[i].kor + pt[i].math + pt[i].eng;
}
setRank(pt, su);
}
void setRank(ST * pt, int su) {
for (int i = 0; i < su; i++) {
pt[i].rank = 1;
for (int j = 0; j < su; j++) {
if (pt[i].sum < pt[j].sum) {
pt[i].rank++;
}
}
}
}
void disp(ST *pt, int su) {
printf("이름\t국어\t영어\t수학\t총점\t순위\n");
for (int i = 0; i < su; i++) {
printf("%s\t%d\t%d\t%d\t%d\t%d\n", pt[i].name, pt[i].kor, pt[i].eng, pt[i].math, pt[i].sum, pt[i].rank);
}
}
참고자료
kg아이티뱅크학원 (자료구조 수업)
[동적할당을 이용한 문자열 처리]{https://m.blog.naver.com/PostView.nhn?blogId=kgsshow1994&logNo=140171859874&proxyReferer=https%3A%2F%2Fwww.google.com%2F}