Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从二进制文件读取并分配给矩阵后,程序崩溃_C_Binaryfiles - Fatal编程技术网

C 从二进制文件读取并分配给矩阵后,程序崩溃

C 从二进制文件读取并分配给矩阵后,程序崩溃,c,binaryfiles,C,Binaryfiles,我有一个任务,创建一个解决9x9数独难题的程序。规格如下: 文件名必须作为参数提供给命令行(编辑:argv[0]不是必需的,只需使用scanf功能从键盘输入即可) 文件必须是二进制文件 必须动态分配所有阵列 二进制文件包含确定坐标和所需数字的数字 e、 g 367表示第3行第6列和第7号 我的程序动态分配一个2D数组,然后分配空间保存文件名,然后打开二进制文件读取数据。使用printf调试我的程序时,数据似乎被适当地保存到importedData数组中,当在数独拼图上分配这些数据时,程序崩溃

我有一个任务,创建一个解决9x9数独难题的程序。规格如下:

  • 文件名必须作为参数提供给命令行(编辑:
    argv[0]
    不是必需的,只需使用
    scanf
    功能从键盘输入即可)
  • 文件必须是二进制文件
  • 必须动态分配所有阵列
  • 二进制文件包含确定坐标和所需数字的数字 e、 g 367表示第3行第6列和第7号
我的程序动态分配一个2D数组,然后分配空间保存文件名,然后打开二进制文件读取数据。使用
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-do
scanf(“%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;