다른 프로그램으로 만든 학생 데이터(1000개 이하 임의로 생성)를 읽어들이고, 정수 하나 입력받아서 해당 위치의 학생데이터를 출력하는 코드인데
예컨대 800개를 만들면 801번째는 데이터가 없을수도 있단말이야
그러면 segmentation fault 에러가 뜨는데 이 에러 대신 학생 데이터가 없다는 에러메시지를 내가 대신 출력해주려면 어떻게 조건을 줘야할까? 도와줘 형들..
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
struct pscore{
int num;
char nme[10];
float sc1;
float sc2;
float sum;
};
struct node
{
struct pscore data;
struct node* next;
};
void insert(struct node* head,struct pscore* val)
{
while(head != NULL)
{
if(head->next == NULL)
{
struct node* new = malloc(sizeof(struct node));
new->data.num = val->num;
strcpy(new->data.nme, val->nme);
new->data.sc1 = val->sc1;
new->data.sc2 = val->sc2;
new->data.sum = val->sum;
new->next = NULL;
head->next = new; // 다음 노드로
break;
}
head = head->next;
}
}
struct node* get(struct node* head, int index)
{
for (int i = 0; i<index; i++)
{
head = head->next;
}
return head;
}
void unmalloc(struct node* head)
{
while (head != NULL)
{
struct node* temp = head->next;
free(head);
head = temp;
}
}
// 모든 노드의 동적메모리 순회하며 해제
int main(int argc, char* argv[]) {
FILE *fp;
int ret;
int input;
if (argc != 2) {
printf("< Usage: ./loader filename>
");
return 1;
}
if((fp = fopen(argv[1], "rb")) == NULL){
perror("Open");
exit(1);
}
struct node* head = malloc(sizeof(struct node));
head->next = NULL;
do
{
struct pscore data;
ret = fread(&data, sizeof(struct pscore), 1, fp);
insert(head, &data);
} while(ret>0); // 가능할때까지 읽음
printf("1000이하의 양의 정수 하나를 입력하십시오: ");
scanf("%d",&input);
struct node* numnode = get(head, input);
if() // <-고민하는부분
{
printf("there is no student data");
}
else{
printf("학번: %d
",numnode->data.num);
printf("이름: %s
",numnode->data.nme);
printf("점수1: %d
",(int)numnode->data.sc1);
printf("점수2: %d
",(int)numnode->data.sc2);
printf("점수합계: %d
",(int)numnode->data.sum);
}
unmalloc(head);
fclose(fp);
return 0;
}
링크드 리스트 순회할 때, 맨 마지막일 때의 조건을 if에 주면 되는 거 아님?
구체적으로 어떻게 주라는거야? 임의의 숫자 입력인데 그러면 800번까지 데이터가 있으면 801번만 되는거아니야? 802 803 ~~ 도 되야되는데
do while 하면서 갯수 세면 되는거 아님?
이걸로 해결이 되네
어딘가에서 없는 메모리 참조한거니까 Null 체크해
Get에서 인덱스가 리스트 크기 넘으면 나오는 에러겠네 Head->next 대입전에 null 체크해서 처리해
get함수의 for루프 안에서 head null체크를 하라는거지?
오류가 어디서 나는데
insert?
아 근데 insert 부분 완전 이상하네 왜 이중루프로 되어있냐 ㅋㅋ
아근데 scanf에서 오류난다는거구나 ㅋㅋ
ㅇㅇ컴파일은 되는데, 생성한 파일에 있는 데이터 갯수보다 높은 숫자를 입력하면 오류가 나는데 그걸 조건을 줘서 오류가 아니라 데이터 없음이라고 출력해주고 싶어서
뭔말인지 알겠음.. 그냥 너가 짠 방식으로는 get 함수 내에 head->next가 NULL인지 체크하는 수 밖게 없는걸..
그니깐 get에서 for 룹 안에 if(head->next) return -1; 뭐 이런거 넣은다음 -1가 뜨면 오류메시지 출력하는 식으로..
return -1은 함수 반환이 포인터형이라 안되는데 어카지
쉽네 걍 get에서 리턴받은 포인터가 null인지 검사하면 되는거아니냐?
아니지. null을 도달하는 순간 head->next에서 null pointer 참조가 되니깐 그 전에 에러가 뜨지
get에서 &(head->next) 로 비교하고 return -1 시키든지 거기서 프린트하던지
if(&(head->next) == NULL) { printf("there is no student data"); }
for루프안에 추가해봤는데 여전히오류나
&는 빼야지...
빼고도해봤어
아니 head = head->next; 위에다가 방금 쓴 if문 쓰고 return 시켜 안그러면 프린트 이후 널포인터 참조하잖아 ㅋㅋ
내가 프린트하라고 했었네 쏘리
if(&(head->next) == NULL) { printf("there is no student data"); return -1; }
일단 프린터 됐으면 리턴은 아무거나 시켜라 어차피 포인터라 0xffffffff이런거 반환후 검사해도 저 주소 할당받아 쓰면 골아프니까
근데 전반적으로 리스트를 더 잘 짤 수 있는 여지가 많음. 저런 노드쓰는거 사람들이 많이 하는거라서, 예제 하나 참고해봐. 일단 insert 할때도, 끝 노드에 하나씩 붙이는게 낫지, 너가 하는 방식은 붙일때마다 처음부터 검사한다음 마지막 도달했을때 붙이는 방식이자나