코딩넘나어려운것
30
2021-06-11 01:56:22 작성 2021-06-11 02:01:44 수정됨
4
119

C언어 도와주세요


Q) 첨부한 binary 파일 s.bin은 다음 구조체의 학생 정보 1000명분을 담고 있다. 

struct AAA

{ char name[12];

long kor; // 국어 점수

long math; // 수학 점수

};

국어, 수학의 점수의 합이 제일 큰 학생의 이름을 화면에 출력하라. (답: jamqnevcjn)



#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <malloc.h>

#include <string.h>

#include <ctype.h>

struct STUDENT
{
	char name[12];
        long kor;			// 국어 점수
	long math;		// 수학 점수
};

struct STUDENT2
{
	char name[12];
	long score;		// 총 점수
};

void sort(struct STUDENT2* data, int n) //구조체를 이용한 소트방법
{
	int i, j;
	struct STUDENT2 tmp;
	for (i = 0; i < n; i++)
	{
		long max = (data + i)->score;//  data[i].score
		int im = i;
		for (j = i; j < n; j++)
		{
			if (max < (data + j)->score)
			{
				max = (data + j)->score; im = j;
			}
		}
		tmp = *(data + i); // tmp = data[i]
		*(data + i) = *(data + im); //data[i] = data[im]
		*(data + im) = tmp; // data[im] = tmp
	}
}

int main()
{
	FILE* f;
	struct STUDENT* s;
	struct STUDENT2* s2;
	int i, n, siz;
	f = fopen("C:\\Users\\sch71\\Desktop\\경희대 3-1\\\\s.bin", "rb");

	if (f == NULL)
	{
		printf("file open error!");
		return 0;
	}

	fseek(f, 0, SEEK_END);
	siz = ftell(f);
	rewind(f);

	s = (struct STUDENT*)malloc(siz);
	if (s == NULL)
	{
		printf("malloc error"); // 동적할당 메모리 
		return 1;
	}
	
        int num = siz / sizeof(struct STUDENT);
	fread(s, sizeof(struct STUDENT), num, f);

	fclose(f);

	s2 = (struct STUDENT2*)malloc(siz);
	if (s2 == NULL)
	{
		printf("malloc error");
		return 1;
	}

	for (i = 0; i < 1000; i++)
	{
		strcpy((s2 + i)->name, (s + i)->name);
		(s2 + i)->score = (s + i)->kor + (s + i)->math ;
	}
	sort(s2, 1000);

	printf("%s", (s2 + 1)->name);

        free(s);
	free(s2);
}



간략하게 코드 설명 드리자면 문제에 나온 구조체와 국어와 수학을 합친 총 점수를 가진 구조체 두 개를 선언 하고 구조체 sort함수도 만들었습니다. 동적메모리 할당 한 후에 구조체 STUDENT 에서 STUDENT2 로 국어+수학 점수와 name을 각각 옮긴 후에 sort함수를 이용해서 구현하려고 하였습니다.  근데 계속  void sort 함수 내에 for 문 안에 있는 if문(34번째 줄)에서 "예외가 throw됨: 쓰기 액세스 위반입니다. max이(가) 0x2F1C7E였습니다." 라고 뜹니다 ㅠㅠ 진짜 6시간정도 붙잡고 있었는데 돌아버릴거같아서 질문남깁니다.. 도와주시면 정말 감사드리겠습니다
0
  • 답변 4

  • Hide_D
    682
    2021-06-11 02:23:09 작성 2021-06-11 02:23:29 수정됨

    문제를 푸는데는 sort 필요 없습니다. STUDENT2도 필요없습니다..... 일단 알아두시구요.


    코드를 한차례 봤는데 딱히 문제가 되는 부분을 못 찾겠네요. 다음 부분들 하나씩 확인해보세요.


    (1) i < 1000, sort(s2, 1000); 이면 안되겠죠. 어쨌든 저 자리엔 num이 들어가야할겁니다.

    (2) s2를 malloc 할땐 siz가 아니라 num * sizeof(struct STUDENT2) 가 맞습니다.

    (3) 사실 sort를 할 때 굳이 배열을 복사해서 할 필요가 없죠 (s[i].kor + s[i].math) < (s[j].kor + s[j].math) 해도 되거든요

    (4) strcpy가 굉장히 위험(?)해보이네요. name[12]에 '\0'이 있다면 다행인데, 만약 없다면..? 어디까지 채워질까요? strncpy가 안전할 것 같구요.

    (5) 만약 잘 돌아간다 하더라도 s2->name 이어야 최고득점일겁니다.

    (6) 32번째 줄은 j = i + 1이 맞을 듯 하구요.

    (7) 39번째 줄은 im이 i랑 다를때 하는게 맞을 것 같네요


    파일에 문제가 있어서 깨지는거라면 (4)번에 설명한대로 strcpy -> strncpy로 해결되지 않을까 싶긴 합니다.

  • 마르세유1
    1k
    2021-06-11 02:26:57

    siz 저게 맞나여?

    그리고 struct 가 = 문이되나여?

    c언어 가물가물 ㅎㅎ;;

    과제하실때 코드 다 친다음에 빌드돌려서 안되는거 잡지마시고, 한줄한줄씩 입력후 디버깅하고 맞는지 다 확인후에 넘어가시는게 시간아끼고 좋을거에요..

    처음배울때는 오류해결하는게 쉽지가 않아 다른사람의 도움이 필요할 때가 많은데 6시간동안 끙끙데셧다면.. 그럴사람이 없을거같은데 오픈채팅방같은데라도 들어가셔서 물어가면서 하세유..

  • 그래안그래
    603
    2021-06-11 08:17:07
    1. 파일을 읽었으면 모든 이름, 수학 점수, 영어점수 를 출력해본다.
    2. 문제가생긴 라인의 바로윗라인에 프린트문을 i,j 등등의 값을 출력해서 어디까지실행되는지 확인한다.
    3. 문제를해결한딘....
  • 코딩넘나어려운것
    30
    2021-06-11 18:23:50

    다들 너무 감사합니다  ㅠㅠ특히 Hide_D 님 strncpy 때문이었습니다..!!! 감사해요 ㅠㅠㅠ

  • 로그인을 하시면 답변을 등록할 수 있습니다.