c언어 구구단 Floating point exception (core dumped)오류
글쓴이: andycho1120 / 작성시간: 수, 2021/03/17 - 12:59오전
구구단을 해결하는 코드를 작성중인데 Floating point exception (core dumped)가 뜨면서 동작을 멈춤니다.
검색이랑 숫자를 출력하는 코드를 통해 어디가 잘못된 부분인지 찾아내려고 해도 잘 안되네요.
아직 배우는 단계라 오류가 일어난 부분만 알려주시면 감사하겠습니다!
tag block #include <stdio.h> /* * 제작자: * 제작일: 2021-3-15 * 내용: 구구단을 자동 풀이 * 구상한 해결 방법 * :1. 1부터 9를 각 번째의 소수로 변환 * 2. 빈칸에는 각 소수들을 모두 곱한 값이 기초값으로 설정되어 있고 가로, 세로줄과 3*3칸에 들어있는 숫자들을 나눗샘을 함으로써 겹치는 숫자들을 제거 * 3. 남은 숫자들을 작은 숫자들부터 삽입시키며 순서대로 채워나감 * 4. 더이상 진행할 수 없지만 빈칸이 남아 있으면 그 전에 채워진 칸이면 전으로 복귀, 그 숫자를 증가 * 5. 반복 *: * */ int main() { int num[9][9]={{0,0,9,8,6,5,4,0,0},{0,0,9,7,4,1,2,0,0},{0,0,4,9,3,2,6,0,0},{2,8,1,5,9,7,3,6,4},{9,4,3,6,2,8,5,7,1},{6,5,7,4,1,3,9,2,8},{0,0,6,3,5,4,1,9,0},{0,0,5,2,8,6,7,0,0},{0,3,2,1,7,9,8,0,0}}; //예시용 구구단 int num_transform[9][9]; //num_count를 담는 배열. 실질적으로 다를 배열임 int i, j, I, J; //for 카운트 int full_count = 81; // full_count 가 0이 되면 모든 칸이 체워짐 int num_count = 2*3*5*7*11*13*17*19*23; //num_count를 통해 부족한 숫자가 무엇인지 판단 int devide_arrangement[9] = {2,3,5,7,11,13,17,19,23}; printf("1"); printf("구구단을 해결하는 프로그램입니다. 구하고자 하는 빈칸은 0으로, 잘못입력했다면 119를 입력하세요\n"); for (i=0; i<9; i++){ for (j=0; j<9; j++){ //printf("%d * %d 칸의 숫자를 입력하세요", i+1, j+1); //scanf("%d",&num[i][j]); //if (num[i][j]==119) j = j-2; if (num[i][j]!=0)full_count = full_count-1; } } printf("2"); int backup[full_count][4]; //소수들의 곱을 저장하는 장치 , [][0] = 값 [][1]= 위치 i [][2] = 위치 j [][3]= devide arrangement배열 저장값 0~8 = 나누기 스택 int x=0; // backup 카운트 printf("빈칸의 갯수는 %d개 입니다.\n", full_count); printf("%d\n", num_count); for ( i=0; i<9; i++){ //num_count를 사용하기 위해 숫자들을 소수로 변환 printf("1."); for ( j=0; j<9; j++){ printf("2."); if (num[i][j]==0){ num_transform[i][j]=1; backup[x][1] = i; backup[x][2] = j; backup[x][3] = 0; x = x+1; printf("3."); } else if (num[i][j]==1)num_transform[i][j]=2; else if (num[i][j]==2)num_transform[i][j]=3; else if (num[i][j]==3)num_transform[i][j]=5; else if (num[i][j]==4)num_transform[i][j]=7; else if (num[i][j]==5)num_transform[i][j]=11; else if (num[i][j]==6)num_transform[i][j]=13; else if (num[i][j]==7)num_transform[i][j]=17; else if (num[i][j]==8)num_transform[i][j]=19; else if (num[i][j]==9)num_transform[i][j]=23; printf("4."); } } printf("4"); //풀이 알고리즘 for (x=0; x< full_count; x++){ backup[x][0]= num_count; i = backup[x][1]-1; //0~8 j = backup[x][2]-1; //0~8 for (I=0; I<9; I++){ // 세로줄 겹침 제거 if ( backup[x][0] % num_transform[I][j]==0) backup[x][0] = backup[x][0] / num_transform[I][j]; } printf("1"); for (J=0; J<9; J++){ // 가로줄 겹침 제거 if ( backup[x][0] % num_transform[i][J]==0) backup[x][0] = backup[x][0] / num_transform[i][J]; } printf("2"); for (I = i - i%3; I <= i - (i-1)%3 + 2; I++){ //같은 3X3칸의 겹침 제거 for (J= j - j%3; J <= j - j%3 +2; J++){ if (backup[x][0] % num_transform[I][J] ==0) backup[x][0] = backup[x][0] / num_transform[I][J]; } } printf("3"); // 반복진행 파트 for(I=1; I<=10;){ int devide_num = devide_arrangement[backup[x-1][3]]; if (backup[x-1][0]%devide_num !=0){ //안나눠짐 if (backup[x-1][3]==8){ //case 1 . 나누기 스택이 가득참(모든 숫자가 들어갈 수가 없음) -> 과거로 회귀해야함 backup[x-1][3]=0; // 기존의 숫자 제거 backup[x-2][3]++; // 이전 나누기 스택 상승 num_transform[i][j]=1; //기존 숫자 제거 x=x-1; //이전 숫자로 복귀 I=11; //반복 탈출 } else if (backup[x-1][3]!=9){ backup[x-1][3]++; I++; } } else if (backup[x-1][0]%devide_num ==0){ //나눠짐 num_transform[i][j] = devide_num; backup[x-1][3]; I=11; //나눠짐 -> 탈출 } } printf("4"); } //back up -> num transform /*for (i=1; i<=full_count; i++){ J = backup[i-1][0]%10; I = (backup[i-1][0] - backup[i-1][0]%10 ) / 10; num_transform[I-1][J-1]= backup[i-1][1]; } */ // num transform -> num for (i=1; i<=9; i++){ for (j=1; j<=9; j++){ if (num_transform[i-1][j-1]=2)num[i-1][j-1]=1; else if (num_transform[i-1][j-1]=3)num[i-1][j-1]=2; else if (num_transform[i-1][j-1]=5)num[i-1][j-1]=3; else if (num_transform[i-1][j-1]=7)num[i-1][j-1]=4; else if (num_transform[i-1][j-1]=11)num[i-1][j-1]=5; else if (num_transform[i-1][j-1]=13)num[i-1][j-1]=6; else if (num_transform[i-1][j-1]=17)num[i-1][j-1]=7; else if (num_transform[i-1][j-1]=19)num[i-1][j-1]=8; else if (num_transform[i-1][j-1]=23)num[i-1][j-1]=9; } } // num 출력 for (i=1; i<=9; i++){ for (j=1; j<=9; j++){ printf("%d ",num[i-1][j-1]); if (j==9) printf("\n"); } } return 0; }
Forums:
구글에서 'floating point
구글에서 'floating point exception (core dumped)'로 검색하면 나오는 첫 번째 링크..
https://stackoverflow.com/questions/13664671/floating-point-exception-core-dump/13664831
이걸 보면 0으로 나머지 연산(%) 할 때 나오는 메시지라고 하네요.
코드를 보니, num_transform 배열이 0을 가지고 있지 않음을 먼저 확인하고 코드를 진행해야 할 듯 합니다.
중간에 if 문 조건에 == 도 써야 하고요.
----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라
아직 배우는 단계라면
글쎄요. 그건 본인이 찾으셔야죠. 다른 분의 힌트를 바탕으로.
core dump 뜬다면 어디서 뜨나요? 여기저기 printf 써 보면 될 거 같네요.
좀 더 전문적으로 한다면 디버거 사용법 익혀보시고요.
세벌 https://sebuls.blogspot.kr/
gcc에 -g 옵션을 주어 디버그정보를 포함하도록
gcc에 -g 옵션을 주어 디버그정보를 포함하도록 컴파일하고 gdb로 실행해 봅니다.
80번째 줄에서 Arithmetic exception 발생했다고 나오고 그 줄도 보여주네요.
그럼 80번째 줄에 break point 설정하고 다시 실행하여 그 줄 실행직전에 세워놓고 상태를 봅니다.
값을 찍어보니 / 및 % 연산의 나누는수 num_transform[I][j]의 값이 0 이고, 이것때문에 예외가 발생한 것이겠습니다. 그 원인은 배열 인덱스중 j가 배열의범위(0 ~ 8)를 벗어난 엉뚱한 값인 -1 을 가리키기 때문이겠고요.
이런 식으로 찾아나가면 해결하실 수 있을겁니다. 위에서 쓴 gdb 명령은 run, break, print 달랑 세 개 뿐이고 시간도 몇 분 걸리지 않습니다. gdb 기본 사용법은 https://jangpd007.tistory.com/54 에 보기 편하게 나오네요.
감사합니다!
도움많이됐습니다!
댓글 달기