C 从二进制文件读取并分配给矩阵后,程序崩溃
我有一个任务,创建一个解决9x9数独难题的程序。规格如下:C 从二进制文件读取并分配给矩阵后,程序崩溃,c,binaryfiles,C,Binaryfiles,我有一个任务,创建一个解决9x9数独难题的程序。规格如下: 文件名必须作为参数提供给命令行(编辑:argv[0]不是必需的,只需使用scanf功能从键盘输入即可) 文件必须是二进制文件 必须动态分配所有阵列 二进制文件包含确定坐标和所需数字的数字 e、 g 367表示第3行第6列和第7号 我的程序动态分配一个2D数组,然后分配空间保存文件名,然后打开二进制文件读取数据。使用printf调试我的程序时,数据似乎被适当地保存到importedData数组中,当在数独拼图上分配这些数据时,程序崩溃
- 文件名必须作为参数提供给命令行(编辑:
不是必需的,只需使用argv[0]
功能从键盘输入即可)scanf
- 文件必须是二进制文件
- 必须动态分配所有阵列
- 二进制文件包含确定坐标和所需数字的数字 e、 g 367表示第3行第6列和第7号
printf
调试我的程序时,数据似乎被适当地保存到importedData
数组中,当在数独拼图上分配这些数据时,程序崩溃或没有正确分配值。这是我的密码:
数独
#include <stdio.h>
#include <stdlib.h>
#include "sudokulib.h"
#define MALLOC_ERROR 0xFF
#define FILE_NOT_FOUND 0xFFF
int main(int argc,char ** argv)
{
char **matrix;
int i,j;
int row,column,num;
FILE * fp;
char * filename;
char * importedData;
matrix=(char **)malloc(9*sizeof(char *));
if (!matrix)
exit(MALLOC_ERROR);
for (i=0;i<9;++i)
{
matrix[i]=(char *)malloc(9*sizeof(char));
if (!matrix[i])
exit(MALLOC_ERROR);
}
initSudoku(matrix);
printf ("Give me the name of data file: ");
filename=(char *)malloc(100*sizeof(char));
if (!filename)
exit(MALLOC_ERROR);
scanf("%s",filename);
fp=fopen(filename,"rb");
if (!fp)
{
printf ("File not found\n");
exit(FILE_NOT_FOUND);
}
importedData=(char *)malloc(sizeof(char)*81*3);
if (!importedData)
exit (MALLOC_ERROR);
fread(importedData,1,243,fp);
i=0;
while (importedData[i] != ' ' && importedData[i+1] != ' ' && importedData[i+2] != ' ' && importedData[i] >= '1' && importedData[i+1] >= '1' && importedData[i+2] >= '1' && importedData[i] <= '9' && importedData[i+1] <= '9' && importedData[i+2] <= '9')
{
row=importedData[i] - 48; /* Convert from ascii code to number */
column=importedData[i+1] - 48;
num=importedData[i+2] - 48;
matrix[row][column]=num;
i=i+3;
}
printf("Sudoku after importing data:\n\n");
printSudoku(matrix);
system("pause");
if (solvePuzzle(matrix))
{
printSudoku(matrix);
}
else
printf ("Puzzle has no solution\n");
fclose(fp);
free(filename);
for (i=0;i<9;++i)
{
free(matrix[i]);
}
free(matrix);
return 0;
}
输出:
Give me the name of data file: data2.bin
Sudoku after importing data:
-------------------
|0|0|0|0|0|0|0|0|0|
-------------------
|0|0|0|0|2|6|0|7|0|
-------------------
|0|6|8|0|0|7|0|0|9|
-------------------
|0|1|9|0|0|0|4|5|0|
-------------------
|0|8|2|0|1|0|0|0|4|
-------------------
|0|0|0|4|6|0|2|9|0|
-------------------
|0|0|5|0|0|0|3|0|2|
-------------------
|0|0|0|9|3|0|0|0|7|
-------------------
|0|0|4|0|0|5|0|0|3|
-------------------
Press any key to continue . . .
编辑2:发现如果使用包含很少数据的非常小的二进制文件(例如,
123245321
工作正常,但如果数据超过9个字节,则拼图会变得混乱。请注意数组是零索引的。因此,您需要再减去一个以获得正确的索引,例如:
row=importedData[i] - 48 - 1;
还要注意,文件中的数字太少。只有96个,但你需要243个
进一步
看看这个:
importedData=(char *)malloc(sizeof(char)*81*3);
...
fread(importedData,1,243,fp);
现在,importedData
中有243个字符(您应该通过查看fread
中的返回代码来检查这一点。在您的情况下,该文件只有96个字符(坏…),但我们假设它可以工作)
然后你会:
i=0;
while (importedData[i] != ' ' &&
importedData[i+1] != ' ' &&
importedData[i+2] != ' ' &&
importedData[i] >= '1' &&
importedData[i+1] >= '1' &&
importedData[i+2] >= '1' &&
importedData[i] <= '9' &&
importedData[i+1] <= '9' &&
importedData[i+2] <= '9')
{
....
}
符合条件
顺便说一句:所有这些硬编码都是错误的。改用#定义
顺便说一句:不要这样做
row=importedData[i] - 48 -1;
但是
请您需要确定问题首先出现在哪里。在解析文件数据的while
中,您读取的数据超过了数组的末尾。请尝试while(importedData[i]&&isdigit(importedData[i])…
Quote:“二进制文件包含确定坐标和所需数字的数字,例如367表示第三行第六列和数字7”哦,亲爱的……老师永远不会知道:“我的程序动态分配2D数组…”不,它没有。它分配一个1D指针数组,其中每个指针指向一个1D数组。有关正确的方法,请参阅:Never-ever-doscanf(“%s”,文件名);
始终设置一个限制,如scanf(“%99s”,文件名)
为了检查字节数,我应该检查fread的返回值吗?这被认为是一种好的做法吗?@JohnM。非常感谢!我所需要做的就是像你说的那样从行和列中减去1,结果成功了。我真愚蠢,竟然忘了从索引中减去1。我还想指出的是,这个数字是一个事实243由9*9*3(9行*9列*(2个坐标+1个数字))相乘而成.试图找到一个更好的解决方案,但我想不出更好的办法,因为我的老师要求它甚至应该解决已经解决的难题。但看起来很愚蠢。@JohnM.Do#定义行9#定义列…
并在代码中使用这些定义,而不是硬代码编号
i=0;
while (importedData[i] != ' ' &&
importedData[i+1] != ' ' &&
importedData[i+2] != ' ' &&
importedData[i] >= '1' &&
importedData[i+1] >= '1' &&
importedData[i+2] >= '1' &&
importedData[i] <= '9' &&
importedData[i+1] <= '9' &&
importedData[i+2] <= '9')
{
....
}
&& i < 243;
row=importedData[i] - 48 -1;
row=importedData[i] - '0' - 1;