gpt4 book ai didi

c - C 语言的数独求解器运行完美,但以段错误结束。找不到来源

转载 作者:行者123 更新时间:2023-11-30 21:08:05 25 4
gpt4 key购买 nike

我用 C 语言编写了一个程序来解决数独难题。它工作得很好,并打印出正确解决的难题,但是,就在程序结束之前,我遇到了段错误,程序崩溃了。我正在努力寻找问题的根源。

抱歉,代码量很大,但我认为如果你们看到了所有内容,它会有所帮助。

(如果有任何不好的 C 实践,我也很抱歉,我很菜鸟。)

#include <stdio.h>
#include <math.h>
#include <stdbool.h>

struct table{
int cells[9][9];
bool fixed[9][9];
};

void enterNum(struct table* t);
void solver(struct table g);
void draw(struct table t);
bool checkInput(struct table* t);

int main(){
setbuf(stdout, NULL);
struct table t;
struct table* tp = &t;

int x, y;
bool loop = true;
while(loop == true){
for(x = 0; x < 9; x++){
for(y = 0; y < 9; y++){
t.cells[x][y] = 0;
}
}
draw(t);
enterNum(tp);
draw(t);

if(checkInput(tp)){
loop = false;
}else{
printf("\n Invalid Soduku Puzzle\n");
}
}
solver(t);
return 0;
}

void draw(struct table t){
printf("\n%d %d %d | %d %d %d | %d %d %d\n", t.cells[0][0], t.cells[0][1], t.cells[0][2], t.cells[0][3], t.cells[0][4], t.cells[0][5], t.cells[0][6], t.cells[0][7], t.cells[0][8]);
printf("%d %d %d | %d %d %d | %d %d %d\n", t.cells[1][0], t.cells[1][1], t.cells[1][2], t.cells[1][3], t.cells[1][4], t.cells[1][5], t.cells[1][6], t.cells[1][7], t.cells[1][8]);
printf("%d %d %d | %d %d %d | %d %d %d\n", t.cells[2][0], t.cells[2][1], t.cells[2][2], t.cells[2][3], t.cells[2][4], t.cells[2][5], t.cells[2][6], t.cells[2][7], t.cells[2][8]);
printf("---------------------\n");
printf("%d %d %d | %d %d %d | %d %d %d\n", t.cells[3][0], t.cells[3][1], t.cells[3][2], t.cells[3][3], t.cells[3][4], t.cells[3][5], t.cells[3][6], t.cells[3][7], t.cells[3][8]);
printf("%d %d %d | %d %d %d | %d %d %d\n", t.cells[4][0], t.cells[4][1], t.cells[4][2], t.cells[4][3], t.cells[4][4], t.cells[4][5], t.cells[4][6], t.cells[4][7], t.cells[4][8]);
printf("%d %d %d | %d %d %d | %d %d %d\n", t.cells[5][0], t.cells[5][1], t.cells[5][2], t.cells[5][3], t.cells[5][4], t.cells[5][5], t.cells[5][6], t.cells[5][7], t.cells[5][8]);
printf("---------------------\n");
printf("%d %d %d | %d %d %d | %d %d %d\n", t.cells[6][0], t.cells[6][1], t.cells[6][2], t.cells[6][3], t.cells[6][4], t.cells[6][5], t.cells[6][6], t.cells[6][7], t.cells[6][8]);
printf("%d %d %d | %d %d %d | %d %d %d\n", t.cells[7][0], t.cells[7][1], t.cells[7][2], t.cells[7][3], t.cells[7][4], t.cells[7][5], t.cells[7][6], t.cells[7][7], t.cells[7][8]);
printf("%d %d %d | %d %d %d | %d %d %d\n\n", t.cells[8][0], t.cells[8][1], t.cells[8][2], t.cells[8][3], t.cells[8][4], t.cells[8][5], t.cells[8][6], t.cells[8][7], t.cells[8][8]);

}

void enterNum(struct table* t){
int oneone, onetwo, onethree, onefour, onefive, onesix, oneseven, oneeight, onenine, twoone, twotwo, twothree, twofour, twofive, twosix, twoseven, twoeight, twonine, threeone, threetwo, threethree, threefour, threefive, threesix, threeseven, threeeight, threenine, fourone, fourtwo, fourthree, fourfour, fourfive, foursix, fourseven, foureight, fournine, fiveone, fivetwo, fivethree, fivefour, fivefive, fivesix, fiveseven, fiveeight, fivenine, sixone, sixtwo, sixthree, sixfour, sixfive, sixsix, sixseven, sixeight, sixnine, sevenone, seventwo, seventhree, sevenfour, sevenfive, sevensix, sevenseven, seveneight, sevennine, eightone, eighttwo, eightthree, eightfour, eightfive, eightsix, eightseven, eighteight, eightnine, nineone, ninetwo, ninethree, ninefour, ninefive, ninesix, nineseven, nineeight, ninenine;

char input[50];
bool loop = true;
while(loop){
printf("Enter the numbers in the first line of the puzzle, 0 for blanks:\n");
if(fgets(input, 50, stdin) == NULL || sscanf(input, "%d %d %d %d %d %d %d %d %d", &oneone, &onetwo, &onethree, &onefour, &onefive, &onesix, &oneseven, &oneeight, &onenine) != 9 || oneone < 0 || oneone > 9 || onetwo < 0 || onetwo > 9 || onethree < 0 || onethree > 9 || onefour < 0 || onefour > 9 || onefive < 0 || onefive > 9 || onesix < 0 || onesix > 9 || oneseven < 0 || oneseven > 9 || oneeight < 0 || oneeight > 9 || onenine < 0 || onenine > 9){
printf("Incorrect input. Try again:\n");
}else{
loop = false;
}
}
loop = true;
while(loop){
printf("Enter the numbers in the second line of the puzzle, 0 for blanks:\n");
if(fgets(input, 50, stdin) == NULL || sscanf(input, "%d %d %d %d %d %d %d %d %d", &twoone, &twotwo, &twothree, &twofour, &twofive, &twosix, &twoseven, &twoeight, &twonine) != 9 || twoone < 0 || twoone > 9 || twotwo < 0 || twotwo > 9 || twothree < 0 || twothree > 9 || twofour < 0 || twofour > 9 || twofive < 0 || twofive > 9 || twosix < 0 || twosix > 9 || twoseven < 0 || twoseven > 9 || twoeight < 0 || twoeight > 9 || twonine < 0 || twonine > 9){
printf("Incorrect input. Try again:\n");
}else{
loop = false;
}
}
loop = true;
while(loop){
printf("Enter the numbers in the third line of the puzzle, 0 for blanks:\n");
if(fgets(input, 50, stdin) == NULL || sscanf(input, "%d %d %d %d %d %d %d %d %d", &threeone, &threetwo, &threethree, &threefour, &threefive, &threesix, &threeseven, &threeeight, &threenine) != 9 || threeone < 0 || threeone > 9 || threetwo < 0 || threetwo > 9 || threethree < 0 || threethree > 9 || threefour < 0 || threefour > 9 || threefive < 0 || threefive > 9 || threesix < 0 || threesix > 9 || threeseven < 0 || threeseven > 9 || threeeight < 0 || threeeight > 9 || threenine < 0 || threenine > 9){
printf("Incorrect input. Try again:\n");
}else{
loop = false;
}
}

loop = true;
while(loop){
printf("Enter the numbers in the fourth line of the puzzle, 0 for blanks:\n");
if(fgets(input, 50, stdin) == NULL || sscanf(input, "%d %d %d %d %d %d %d %d %d", &fourone, &fourtwo, &fourthree, &fourfour, &fourfive, &foursix, &fourseven, &foureight, &fournine) != 9 || fourone < 0 || fourone > 9 || fourtwo < 0 || fourtwo > 9 || fourthree < 0 || fourthree > 9 || fourfour < 0 || fourfour > 9 || fourfive < 0 || fourfive > 9 || foursix < 0 || foursix > 9 || fourseven < 0 || fourseven > 9 || foureight < 0 || foureight > 9 || fournine < 0 || fournine > 9){
printf("Incorrect input. Try again:\n");
}else{
loop = false;
}
}

loop = true;
while(loop){
printf("Enter the numbers in the fifth line of the puzzle, 0 for blanks:\n");
if(fgets(input, 50, stdin) == NULL || sscanf(input, "%d %d %d %d %d %d %d %d %d", &fiveone, &fivetwo, &fivethree, &fivefour, &fivefive, &fivesix, &fiveseven, &fiveeight, &fivenine) != 9 || fiveone < 0 || fiveone > 9 || fivetwo < 0 || fivetwo > 9 || fivethree < 0 || fivethree > 9 || fivefour < 0 || fivefour > 9 || fivefive < 0 || fivefive > 9 || fivesix < 0 || fivesix > 9 || fiveseven < 0 || fiveseven > 9 || fiveeight < 0 || fiveeight > 9 || fivenine < 0 || fivenine > 9){
printf("Incorrect input. Try again:\n");
}else{
loop = false;
}
}

loop = true;
while(loop){
printf("Enter the numbers in the sixth line of the puzzle, 0 for blanks:\n");
if(fgets(input, 50, stdin) == NULL || sscanf(input, "%d %d %d %d %d %d %d %d %d", &sixone, &sixtwo, &sixthree, &sixfour, &sixfive, &sixsix, &sixseven, &sixeight, &sixnine) != 9 || sixone < 0 || sixone > 9 || sixtwo < 0 || sixtwo > 9 || sixthree < 0 || sixthree > 9 || sixfour < 0 || sixfour > 9 || sixfive < 0 || sixfive > 9 || sixsix < 0 || sixsix > 9 || sixseven < 0 || sixseven > 9 || sixeight < 0 || sixeight > 9 || sixnine < 0 || sixnine > 9){
printf("Incorrect input. Try again:\n");
}else{
loop = false;
}
}

loop = true;
while(loop){
printf("Enter the numbers in the seventh line of the puzzle, 0 for blanks:\n");
if(fgets(input, 50, stdin) == NULL || sscanf(input, "%d %d %d %d %d %d %d %d %d", &sevenone, &seventwo, &seventhree, &sevenfour, &sevenfive, &sevensix, &sevenseven, &seveneight, &sevennine) != 9 || sevenone < 0 || sevenone > 9 || seventwo < 0 || seventwo > 9 || seventhree < 0 || seventhree > 9 || sevenfour < 0 || sevenfour > 9 || sevenfive < 0 || sevenfive > 9 || sevensix < 0 || sevensix > 9 || sevenseven < 0 || sevenseven > 9 || seveneight < 0 || seveneight > 9 || sevennine < 0 || sevennine > 9){
printf("Incorrect input. Try again:\n");
}else{
loop = false;
}
}

loop = true;
while(loop){
printf("Enter the numbers in the eighth line of the puzzle, 0 for blanks:\n");
if(fgets(input, 50, stdin) == NULL || sscanf(input, "%d %d %d %d %d %d %d %d %d", &eightone, &eighttwo, &eightthree, &eightfour, &eightfive, &eightsix, &eightseven, &eighteight, &eightnine) != 9 || eightone < 0 || eightone > 9 || eighttwo < 0 || eighttwo > 9 || eightthree < 0 || eightthree > 9 || eightfour < 0 || eightfour > 9 || eightfive < 0 || eightfive > 9 || eightsix < 0 || eightsix > 9 || eightseven < 0 || eightseven > 9 || eighteight < 0 || eighteight > 9 || eightnine < 0 || eightnine > 9){
printf("Incorrect input. Try again:\n");
}else{
loop = false;
}
}

loop = true;
while(loop){
printf("Enter the numbers in the ninth line of the puzzle, 0 for blanks:\n");
if(fgets(input, 50, stdin) == NULL || sscanf(input, "%d %d %d %d %d %d %d %d %d", &nineone, &ninetwo, &ninethree, &ninefour, &ninefive, &ninesix, &nineseven, &nineeight, &ninenine) != 9 || nineone < 0 || nineone > 9 || ninetwo < 0 || ninetwo > 9 || ninethree < 0 || ninethree > 9 || ninefour < 0 || ninefour > 9 || ninefive < 0 || ninefive > 9 || ninesix < 0 || ninesix > 9 || nineseven < 0 || nineseven > 9 || nineeight < 0 || nineeight > 9 || ninenine < 0 || ninenine > 9){
printf("Incorrect input. Try again:\n");
}else{
loop = false;
}
}

t->cells[0][0] = oneone;
t->cells[0][1] = onetwo;
t->cells[0][2] = onethree;
t->cells[0][3] = onefour;
t->cells[0][4] = onefive;
t->cells[0][6] = oneseven;
t->cells[0][5] = onesix;
t->cells[0][7] = oneeight;
t->cells[0][8] = onenine;
t->cells[1][0] = twoone;
t->cells[1][1] = twotwo;
t->cells[1][2] = twothree;
t->cells[1][3] = twofour;
t->cells[1][4] = twofive;
t->cells[1][6] = twoseven;
t->cells[1][5] = twosix;
t->cells[1][7] = twoeight;
t->cells[1][8] = twonine;
t->cells[2][1] = threetwo;
t->cells[2][0] = threeone;
t->cells[2][2] = threethree;
t->cells[2][3] = threefour;
t->cells[2][4] = threefive;
t->cells[2][5] = threesix;
t->cells[2][6] = threeseven;
t->cells[2][7] = threeeight;
t->cells[2][8] = threenine;
t->cells[3][0] = fourone;
t->cells[3][1] = fourtwo;
t->cells[3][3] = fourfour;
t->cells[3][2] = fourthree;
t->cells[3][4] = fourfive;
t->cells[3][5] = foursix;
t->cells[3][6] = fourseven;
t->cells[3][7] = foureight;
t->cells[3][8] = fournine;
t->cells[4][0] = fiveone;
t->cells[4][1] = fivetwo;
t->cells[4][2] = fivethree;
t->cells[4][3] = fivefour;
t->cells[4][4] = fivefive;
t->cells[4][6] = fiveseven;
t->cells[4][5] = fivesix;
t->cells[4][7] = fiveeight;
t->cells[4][8] = fivenine;
t->cells[5][0] = sixone;
t->cells[5][2] = sixthree;
t->cells[5][1] = sixtwo;
t->cells[5][3] = sixfour;
t->cells[5][4] = sixfive;
t->cells[5][5] = sixsix;
t->cells[5][6] = sixseven;
t->cells[5][7] = sixeight;
t->cells[5][8] = sixnine;
t->cells[6][0] = sevenone;
t->cells[6][1] = seventwo;
t->cells[6][2] = seventhree;
t->cells[6][3] = sevenfour;
t->cells[6][5] = sevensix;
t->cells[6][4] = sevenfive;
t->cells[6][6] = sevenseven;
t->cells[6][8] = sevennine;
t->cells[6][7] = seveneight;
t->cells[7][0] = eightone;
t->cells[7][1] = eighttwo;
t->cells[7][2] = eightthree;
t->cells[7][4] = eightfive;
t->cells[7][3] = eightfour;
t->cells[7][5] = eightsix;
t->cells[7][6] = eightseven;
t->cells[7][7] = eighteight;
t->cells[7][8] = eightnine;
t->cells[8][0] = nineone;
t->cells[8][1] = ninetwo;
t->cells[8][2] = ninethree;
t->cells[8][3] = ninefour;
t->cells[8][4] = ninefive;
t->cells[8][5] = ninesix;
t->cells[8][6] = nineseven;
t->cells[8][7] = nineeight;
t->cells[8][8] = ninenine;
}

bool checkInput(struct table* t){

for(int z = 0; z < 9; z ++){
for(int y = 0; y < 9; y++){
for(int x = 0; x < 9; x++){
if(t->cells[y][z] == t->cells[y][x] && t->cells[y][z] != 0 && z != x){
return false;
}
}
}
}

for(int z = 0; z < 9; z ++){
for(int y = 0; y < 9; y++){
for(int x = 0; x < 9; x++){
if(t->cells[z][y] == t->cells[x][y] && t->cells[z][y] != 0 && z != x){
return false;
}
}
}
}

for(int x = 0; x < 3; x++ ){
for(int y = 0; y < 3; y ++){
for(int m = 0; m < 3; m++){
for(int n = 0; n < 3; n ++){
if(t->cells[x][y] == t->cells[m][n] && x != m && y != n && t->cells[x][y] != 0){
return false;
}
}
}
}
}

for(int x = 3; x < 6; x++ ){
for(int y = 0; y < 3; y ++){
for(int m = 3; m < 6; m++){
for(int n = 0; n < 3; n ++){
if(t->cells[x][y] == t->cells[m][n] && x != m && y != n && t->cells[x][y] != 0){
return false;
}
}
}
}
}

for(int x = 6; x < 9; x++ ){
for(int y = 0; y < 3; y ++){
for(int m = 6; m < 9; m++){
for(int n = 0; n < 3; n ++){
if(t->cells[x][y] == t->cells[m][n] && x != m && y != n && t->cells[x][y] != 0){
return false;
}
}
}
}
}

for(int x = 0; x < 3; x++ ){
for(int y = 3; y < 6; y ++){
for(int m = 0; m < 3; m++){
for(int n = 3; n < 6; n ++){
if(t->cells[x][y] == t->cells[m][n] && x != m && y != n && t->cells[x][y] != 0){
return false;
}
}
}
}
}

for(int x = 3; x < 6; x++ ){
for(int y = 3; y < 6; y ++){
for(int m = 3; m < 6; m++){
for(int n = 3; n < 6; n ++){
if(t->cells[x][y] == t->cells[m][n] && x != m && y != n && t->cells[x][y] != 0){
return false;
}
}
}
}
}

for(int x = 6; x < 9; x++ ){
for(int y = 3; y < 6; y ++){
for(int m = 6; m < 9; m++){
for(int n = 3; n < 6; n ++){
if(t->cells[x][y] == t->cells[m][n] && x != m && y != n && t->cells[x][y] != 0){
return false;
}
}
}
}
}

for(int x = 0; x < 3; x++ ){
for(int y = 6; y < 9; y ++){
for(int m = 0; m < 3; m++){
for(int n = 6; n < 9; n ++){
if(t->cells[x][y] == t->cells[m][n] && x != m && y != n && t->cells[x][y] != 0){
return false;
}
}
}
}
}

for(int x = 3; x < 6; x++ ){
for(int y = 6; y < 9; y ++){
for(int m = 3; m < 6; m++){
for(int n = 6; n < 9; n ++){
if(t->cells[x][y] == t->cells[m][n] && x != m && y != n && t->cells[x][y] != 0){
return false;
}
}
}
}
}

for(int x = 6; x < 9; x++ ){
for(int y = 6; y < 9; y ++){
for(int m = 6; m < 9; m++){
for(int n = 6; n < 9; n ++){
if(t->cells[x][y] == t->cells[m][n] && x != m && y != n && t->cells[x][y] != 0){
return false;
}
}
}
}
}

return true;
}

void solver(struct table g){

struct table* t = &g;

for(int x = 0; x < 9; x++){
for(int y = 0; y < 9; y++){
if(t->cells[x][y] != 0){
t->fixed[x][y] = true;
}else{
t->fixed[x][y] = false;
}
}
}

for(int x = 0; x < 9; x++){
for(int y = 0; y < 9; y++){
if(t->fixed[x][y] == false){
t->cells[x][y]++;
while(!checkInput(t)){
t->cells[x][y]++;
}
if(t->cells[x][y] == 10){
t->cells[x][y] = 0;
if(y == 0){
y = 7;
x = x -2;
}else{
y = y - 2;
}
while(t->fixed[x][y+1] == true){
y--;
}
}
}
}
}

printf("Your solved puzzle is: \n");
draw(g);

}

最佳答案

不要跨越 y 索引低于 0 或高于 8 的表边界,并为所有 while 循环添加保护,例如:

    while  ( (y>=-1) && (y < 8) && (t->fixed[x][y+1] == true) ) {...}

while ( (y>= 1) && (y < 8) && (t->fixed[x][y+1] == true) ) {y--;}

关于c - C 语言的数独求解器运行完美,但以段错误结束。找不到来源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40441768/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com