gpt4 book ai didi

c - 从文件中读取矩阵

转载 作者:太空宇宙 更新时间:2023-11-04 02:27:33 25 4
gpt4 key购买 nike

这是我从文件中读取矩阵的函数。在我第一行的文本文件中,第 2 行是 n,第 3 行是 m,接下来的两行是矩阵。我没有错误,但我的程序“停止工作”,我不知道为什么。谢谢你!我主要有:readmatrix(n,m,a, "text.txt");

int readmatrix(int* n,int *m, int a[*n][*m], char* filename){
FILE *pf;
int i,j;
pf = fopen (filename, "rt");
if (pf == NULL)
return 0;
fscanf (pf, "%d",n);
for (i=0;i<*n;i++)
{
for(j=0;j<*m;j++)
fscanf (pf, "%d", &a[i][j]);
}
fclose (pf);
return 1;
}

最佳答案

如果您的编译器支持 VLA 或者您使用的是 C99,那么您可以这样做:

#include <stdio.h>

int readmatrix(size_t rows, size_t cols, int (*a)[cols], const char* filename)
{

FILE *pf;
pf = fopen (filename, "r");
if (pf == NULL)
return 0;

for(size_t i = 0; i < rows; ++i)
{
for(size_t j = 0; j < cols; ++j)
fscanf(pf, "%d", a[i] + j);
}


fclose (pf);
return 1;
}

int main(void)
{
int matrix[2][3];

readmatrix(2, 3, matrix, "file.dat");

for(size_t i = 0; i < 2; ++i)
{
for(size_t j = 0; j < 3; ++j)
printf("%-3d ", matrix[i][j]);
puts("");
}

return 0;
}

file.dat 看起来像这样:

1 2 3
4 5 6

我的程序的输出是

$ ./a 
1 2 3
4 5 6

请注意,这是一个基本示例,您应该始终检查的返回值fscanf。如果 file.dat 只有一行,那么您就会遇到麻烦。还文件中没有数字,您也会在矩阵。

我建议使用 fgets 读取整行,然后使用sscanf 或一些其他函数,如 strtok,那么它会更容易使用react输入文件中的错误。


编辑

像这样读取文件的一种更可靠的方法是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>


int **readmatrix(size_t *rows, size_t *cols, const char *filename)
{
if(rows == NULL || cols == NULL || filename == NULL)
return NULL;

*rows = 0;
*cols = 0;

FILE *fp = fopen(filename, "r");

if(fp == NULL)
{
fprintf(stderr, "could not open %s: %s\n", filename, strerror(errno));
return NULL;
}

int **matrix = NULL, **tmp;

char line[1024];

while(fgets(line, sizeof line, fp))
{
if(*cols == 0)
{
// determine the size of the columns based on
// the first row
char *scan = line;
int dummy;
int offset = 0;
while(sscanf(scan, "%d%n", &dummy, &offset) == 1)
{
scan += offset;
(*cols)++;
}
}

tmp = realloc(matrix, (*rows + 1) * sizeof *matrix);

if(tmp == NULL)
{
fclose(fp);
return matrix; // return all you've parsed so far
}

matrix = tmp;

matrix[*rows] = calloc(*cols, sizeof *matrix[*rows]);

if(matrix[*rows] == NULL)
{
fclose(fp);
if(*rows == 0) // failed in the first row, free everything
{
fclose(fp);
free(matrix);
return NULL;
}

return matrix; // return all you've parsed so far
}

int offset = 0;
char *scan = line;
for(size_t j = 0; j < *cols; ++j)
{
if(sscanf(scan, "%d%n", matrix[*rows] + j, &offset) == 1)
scan += offset;
else
matrix[*rows][j] = 0; // could not read, set cell to 0
}

// incrementing rows
(*rows)++;
}

fclose(fp);

return matrix;
}

int main(void)
{

size_t cols, rows;
int **matrix = readmatrix(&rows, &cols, "file.dat");

if(matrix == NULL)
{
fprintf(stderr, "could not read matrix\n");
return 1;
}


for(size_t i = 0; i < rows; ++i)
{
for(size_t j = 0; j < cols; ++j)
printf("%-3d ", matrix[i][j]);
puts("");

}


// freeing memory
for(size_t i = 0; i < rows; ++i)
free(matrix[i]);
free(matrix);

return 0;
}

现在 file.dat 看起来像这样:

1 2 3 4 
4 5 6 5
9 8 8 7
5 5 5 5
1 1 1 1

输出是

1   2   3   4   
4 5 6 5
9 8 8 7
5 5 5 5
1 1 1 1

在这个例子中,我只计算第一列的列数,将该数字用于所有其他列。如果输入文件的行少第一行的列,则缺失值存储为 0。如果它有行将修剪比行更多的列。

我这样计算行数:

            while(sscanf(scan, "%d%n", &dummy, &offset) == 1)
{
scan += offset;
(*cols)++;
}

首先我声明一个指针scan指向line,这样我就可以修改指针不丢失原来的线。 sscanf中的%n不计入成功转换的次数,返回 scan 的位置它停止阅读。我用它来循环 sscanf。我明确地检查sscanf 返回 1,如果是这样,我会增加列数并我更新 scan 以更新到 sscanf 停止读取的位置。这允许我继续扫描直到到达行尾。我用一个解析所有整数的类似技术。

关于c - 从文件中读取矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48936647/

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