개발자

C언어 오류 수정 질문

2023년 11월 07일조회 162

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define NO_STD 5 #define NO_SUB 4 struct ICT { int num; char name[20]; int score[NO_SUB]; int sum; float arg; int no; float total; char grade; }; int main(void) { int i, j; struct ICT std[NO_STD]; for (i = 0; i < NO_STD; i++) { std[i].sum = 0; printf("학번을 입력하세요 :"); scanf_s("%d", &std[i].num); printf("이름을 입력하세요 :"); scanf_s("%s", &std[i].name, sizeof(std[i].name)); for (j = 0; j < NO_SUB; j++) { printf("%d번째 학생의 %d번째 과목 점수를 입력하세요 :", i + 1, j + 1); scanf_s("%d", &std[i].score[j]); std[i].sum += std[i].score[j]; } std[i].arg = (float)std[i].sum / NO_SUB; printf("결석을 입력하세요 :"); scanf_s("%d", &std[i].no); std[i].total = std[i].arg - std[i].no * 0.5; if (std[i].total > 89) { std[i].grade = 'A'; } else if (std[i].total > 79) { std[i].grade = 'B'; } else if (std[i].total > 69) { std[i].grade = 'C'; } else { std[i].grade = 'F'; } } printf("순서\t학번\t이름\t중간\t중간2\t중간3\t중간4\t합계\t평균\t결석\t최종\t학점\n"); for (i = 0; i < NO_STD; i++) { printf("%d\t%d\t%s\t", i + 1, std[i].num, std[i].name); for (j = 0; j < NO_SUB; j++) { printf("%d\t", std[i].score[j]); } printf("%3d\t%.2f\t%d\t%.2f\t%s\n", std[i].sum, std[i].arg, std[i].no, std[i].total, std[i].grade); } } 에서 F11.로 한단계씩 디버그하기를 하면은 다 잘되는데 마지막 printf에서 예외 발생(0x00007FFFCFBAAC87(ucrtbased.dll), 2차중간고사.exe): 0xC0000005: 0xFFFFFFFFFFFFFFFF 위치를 읽는 동안 액세스 위반이 발생했습니다.. 이라고 뜨면서 합계부터 출력이 안됩니다. 이거 혹시 어떻게 해결해야되는지 아시나요....

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.

답변 2

인기 답변

이승현님의 프로필 사진

printf("%3d\t%.2f\t%d\t%.2f\t%s\n", std[i].sum, std[i].arg, std[i].no, std[i].total, std[i].grade); -> printf("%3d\t%.2f\t%d\t%.2f\t%c\n", std[i].sum, std[i].arg, std[i].no, std[i].total, std[i].grade); 로 하시면 됩니다. %s는 string을 찍는 거라서, 1byte(char)씩 움직이면서 0(null)이 나올때 까지 계속합니다. 0~NO_STD-2 까지는 memory layout상, { num, ..., grade } { num, ..., grade }의 형태라서, num에서 몇개 더가면 0이 되는 byte가 나와서 넘어갈 수 도 있는데, std[NO_STD-1] 의 { num, ..., grade } 다음에는 그냥 쓰레기 값입니다. 이경우에는 후속으로 나오는 byte중, 어떤 것이 0이 될지 몰라서 계속 접근하다가, segmentation fault가 나게 됩니다.(운이 좋으면 안 날 수도 있어요 ㅎㅎ) 그래서 data형이 char이니까, %c 를 해주셔야 안전합니다. C는 굉장히 low-level 언어이기 때문에, 어느 영역까지 읽을 것인지에 대한 guard line을 정확히 해주지 않으면, 쉽게 crash 나게되고, 심지어 보안의 허점이 되곤 합니다. 그래서 buffer의 크기를 제한 할 수 없는 strcpy, sprintf 보다 strncpy, snprintf()와 같이 정해진 크기의 buffer안에서 operation 하는 습관을 들이시는 것이 좋습니다.

doublecicken1님의 프로필 사진

doublecicken1

작성자

명지전문대학교 정보통신공학과2023년 11월 07일

너무 감사합니다. 프로그래밍이라는게 하나의 단어만 틀려도 안돌아가니 어렵네요.그래도 내가 원하는대로 프로그램이 돌아갈때 정말 기쁜것같습니다. 앞으로 열심히 공부해서 좋은 프로그래머로 성장하겠습니다.

인기 답변

박병석님의 프로필 사진

ChatGPT 로 풀어봤어요... ------------ C 언어 코드인데, 마지막에 에러가 뜨는데 수정해 줘 ..... 코드 고대로.... ------------ ==> 주어진 C 언어 코드에서 마지막 줄에 에러가 발생하는 이유는, printf 문장의 형식 지정자와 실제 인수의 타입이 일치하지 않기 때문입니다. 구체적으로, "%s\n" 형식 지정자를 사용하여 문자열을 출력하려고 하지만, 실제로는 문자 하나('A', 'B', 'C', 'F')만을 출력하려고 합니다. 따라서, 아래와 같이 수정하면 됩니다. printf("%d\t%d\t%s\t", i + 1, std[i].num, std[i].name); for (j = 0; j < NO_SUB; j++) { printf("%d\t", std[i].score[j]); } printf("%3d\t%.2f\t%d\t%.2f\t%c\n", std[i].sum, std[i].arg, std[i].no, std[i].total, std[i].grade); 위 코드에서는 마지막 줄의 printf 문장에서 "%s\n"을 "%c\n"으로 수정하여 문자 하나를 출력하도록 변경하였습니다. 이제 코드를 실행하면 에러 없이 원하는 결과를 출력할 수 있을 것입니다. ------------ 정확히 이승현님이 말씀하신 부분을 지적하고 있네요.. ㅎㅎ

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2023년 11월 07일

마지막 `printf`함수에서 포맷 스펙피커 `%s\n`를 사용하여 학점을 출력하고 있습니다. 하지만 이는 문자열을 가리키기 때문에 오류가 발생합니다. `std[i].grade`는 단일 문자이므로, 해당 부분의 포맷 스펙피커를 `%c\n`으로 변경해야 합니다. 그러므로, 마지막 `printf` 함수 호출은 다음과 같아야 합니다: ```c printf("%d\t%d\t%s\t", i + 1, std[i].num, std[i].name); for (j = 0; j < NO_SUB; j++) { printf("%d\t", std[i].score[j]); } printf("%3d\t%.2f\t%d\t%.2f\t%c\n", std[i].sum, std[i].arg, std[i].no, std[i].total, std[i].grade); ``` 이렇게 수정하면 코드가 정상적으로 실행되어야 합니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!