所以,我有一个包含NxM大小矩阵的文件。例如:
P2
3 3 1
1 0 0
0 1 0
0 0 1
' P2'只是一个无用的指标,第一个' 3'表示有多少列,第二列是' 3'表示有多少行,' 1'表示矩阵的数字中的最大值。该矩阵存储在如下数据结构中:
typedef struct {
int c; // columns
int l; // lines
unsigned char max; // max value
unsigned char** data // variable to store matrix's numbers
} Matrix;
为了将数字从文件存储到数据变量,我使用了fread函数,如下所示:
Matrix* newMatrix = NULL;
newMatrix = malloc(sizeof(Matrix));
FILE* fp = NULL;
fp = fopen(matrixfile, "r");
long size;
fseek(matrixfile, 0, SEEK_END);
size = ftell(matrixfile);
newMatrix->data = malloc(size);
// Jump the 'P2' bytes.
fseek(matrixfile, 2, SEEK_SET);
// Get the c, l and max values.
fscanf(matrixfile, "%i %i %i", &newMatrix->c, &newMatrix->l, &newMatrix->max);
// Jump a '\n' character.
fseek(matrixfile, 1, SEEK_CUR);
// Get matrix's numbers.
fread(newMatrix->data, 1, size, matrixfile);
好的,我将矩阵的数字存储为' unsigned char **数据'变量。但现在我需要处理这些数字,所以我试图将这个字符串转换为整数矩阵。我试着做这样的事情:
void StringtoInt (Matrix* str){
int matrixAux[str->l][str->c], i, j;
for(i=0; i<str->l; i++)
for(j=0; j<str->c; j++)
sscanf(str->data, "%i ", &matrixAux[i][j]);
}
好吧,我理解为什么这不起作用以及为什么我的&#C3; matrixAux&#39;将是一个只有1&s的CxL矩阵。但是我不知道在不知道矩阵中有多少元素的情况下使用sscanf的任何方法。
所以,我的问题是:是否有更好的方法来转换未签名的char **数据&#39;字符串成整数矩阵而不改变数据&#39; type(unsigned char **)?
我想也许我只是使用错误的方法将文件的矩阵存储到数据变量(fread函数)中,或者搞乱指针语法的指针。但我也没有看到任何其他好的选择。
答案 0 :(得分:2)
问题1:计算data
如果矩阵存储为文本文件,就像您发布的一样,使用
fseek(matrixfile, 0, SEEK_END);
size = ftell(matrixfile);
提出data
的大小是不正确的。
您需要做的就是阅读行数和列数,然后,您可以使用numRows * numCols
来提出data
的大小。
问题2:为data
使用
newMatrix->data = malloc(size);
为data
分配内存似乎表明对内存的分配方式缺乏了解。
data
的类型为char**
。
malloc(size)
为大小为size
的字符数组分配内存。将malloc(size)
的返回值分配给newMatrix->data
是错误的。
您需要的是:
newMatrix->data = malloc(numRows*sizeof(char*)); // Assuming you read numRows first.
for ( int i = 0; < numRows; ++i )
{
newMatrix->data[i] = malloc(numCols);
}
阅读数据
现在您可以使用以下方法从文件中读取数据:
for ( int i = 0; < numRows; ++i )
{
for ( int j = 0; j < numCols; ++j )
{
int number;
if ( fscanf(matrixfile, "%d", &number) == 1 )
{
// Check that number is within range.
// ...
newMatrix->data[i][j] = number;
}
else
{
// Unable to read the number.
// Deal with the error.
exit(1);
}
}
}
答案 1 :(得分:0)
要将数字直接扫描到unsigned char
,请使用"hhu"
(自C99起可用的"hh"
)
sscanf(str->data, "%hhu", &matrixAux[i][j]);
由于文本文件fseek(matrixfile, 2, SEEK_SET);
是UB。只能寻找开始,开始或之前的tell()
偏移量。相反,寻求开始和fscanf(matrixfile, "P2 %i %i %i", &newMatrix->c, &newMatrix->l, &newMatrix->max);
。始终检查fscanf()
结果。