자료구조(9) 숙제(4+) 문자열 포인터

이전 코드 구조체 안 배열을 char *로 바꿔서 풀어보기.

동적할당을 이용한 문자열 처리
  1. 문자열을 입력받기 위한 충분한 크기의 문자 배열을 선언한다.
  2. 문자열을 입력 받는다.
  3. 입력된 문자열의 길이를 계산하여 그 크기에 맞게 기억공간을 동적으로 할당받는다.(널문자까지 포함한 메모리를 할당하기);
  4. 문자열을 복사한다.

관련 내용 조금 공부

문자열 포인터의 배열

2차원 배열 대신, 문자배열의 포인터를 이용해서 정리. 이는 문자열의 최대 길이로 각 요소의 길이가 고정되는 2차원 배열과는 달리, 개별 문자열의 시작 위치에 대한 포인터들의 배열이며, 따라서 사용되지 않고 남는 메모리가 없다.

동적으로 할당되는 배열 사용하기
  1. 기본적으로 “문자열 배열”은 char**타입으로 지정하고 문자열의 적정 개수 혹은 최소 개수에서 시작한다. 그리고 초기 상태에서 문자열을 저장하기 위한 메모리 공간은 전혀 할당하지 않은 상태로 시작한다.

  2. 문자열 배열에 새로운 문자열을 삽입하려면, 삽입하고자 하는 문자열을 저장할 메모리 공간을 동적으로 할당하고, 이 영역으로 문자열을 복사한다. 그리고 문자열 배열의 i번재 칸의 값은 새롭게 할당할 지점의 포인터를 저장한다.

  3. 이와 같은 방식으로 배열을 다루면, 배열 자체는 문자열 포인터를 저장하는 연속적인 구간이 된다. 그리고 각 포인터가 가리키는 곳은 별도로 할당된 메모리 영역이며, 이 경우 문자열을 사용하는 것에 대해서는 실제 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}

0%