如何在C语言中从文本文件读取内容并存储到矩阵中

5

首先声明,我对编程完全是新手,所以请原谅我的错误。我现在正在尝试读取一个非常大的文本文件,它有大约1000000行和4列。

56.154 59.365 98.3333 20.11125
98.54 69.3645 52.3333 69.876
76.154 29.365 34.3333 75.114
37.154 57.365 7.0 24.768
........
........

我想读取它们并将它们存储到矩阵中,这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

int main()
{
  int i;
  int j;

/*matrix*/
int** mat=malloc(1000000*sizeof(int));
for(i=0;i<1000000;++i)
mat[i]=malloc(4*sizeof(int));


  FILE *file;
  file=fopen("12345.txt", "r");

 for(i = 0; i < 1000; i++)
  {
      for(j = 0; j < 4; j++) 
      {
       if (!fscanf(file, " %c", &mat[i][j])) 
           break;
       mat[i][j] -= '0'; /* I found it from internet but it doesn't work*/
       printf("\n",mat[i][j]);
      }

  }
  fclose(file);
}

结果是我的矩阵中没有任何东西。希望你能帮忙。非常感谢您的任何帮助。

1
我相信你很快就会得到答案,但我的建议是:学会调试。使用调试器,逐步执行程序。检查变量并检查它们是否包含您所期望的内容。然后,您很快就能自己解决这样的问题。 - Martin R
当然,别忘了阅读文档。提示:fscanf()中的%c格式是用来做什么的? - Martin R
问题很多。新手,你应该将其分解为最简单的部分,并从那里开始工作。例如,首先解决数组访问/动态内存分配问题,然后再着手将文件中的单个值读入适当的变量(float)。 - Macattack
@MartinR 感谢您的建议,实际上我阅读了很多文档,比如《C程序设计语言》和一些教程,但是当我写代码时我并不能真正记住。我会学习调试,这听起来很实用。 - rooooookie
@AlterMann 我试过了,但一开始它并没有起作用。但我想知道,如果加入一个额外的命令,会改变我的代码或使程序变慢吗?谢谢。 - rooooookie
显示剩余2条评论
3个回答

7
许多问题需要考虑,以下是一些建议,当然还要看评论。
int main()
{
  int i;
  int j;

/*matrix*/
/*Use double , you have floating numbers not int*/

double** mat=malloc(1000000*sizeof(double*)); 
for(i=0;i<1000000;++i)
mat[i]=malloc(4*sizeof(double));


  FILE *file;
  file=fopen("1234.txt", "r");

 for(i = 0; i < 1000; i++)
  {
      for(j = 0; j < 4; j++) 
      {
  //Use lf format specifier, %c is for character
       if (!fscanf(file, "%lf", &mat[i][j])) 
           break;
      // mat[i][j] -= '0'; 
       printf("%lf\n",mat[i][j]); //Use lf format specifier, \n is for new line
      }

  }
  fclose(file);
}

谢谢!它运行得很好,现在我会回去仔细阅读基本概念。 - rooooookie

1
  1. fscanf("%c", ...) 只能扫描单个字符(例如 '5')。通过减去 '0',您可以从字符 '5' 获得整数值 5。您可以使用 "%d" 扫描仅由数字组成的整数(不包括格式字符),或者使用 "%f" 扫描浮点数(不确定 56.154 是否应被解释为 "56 千 154"(欧洲大陆)或 "56 加上 154/1000"(英国 / 美国)(世界其他地方:请不要生气,我只是不知道)

  2. printf("\n", ...): 您忘记使用任何格式化字符串,例如 %d (int)、%f (float)... 因此,您的参数将不会被打印出来,只有换行符本身。

  3. int** mat=malloc(1000000*sizeof(int)); 在这里你正在分配一个 int * 数组,所以它应该是 int** mat=malloc(1000000*sizeof(int *));

编辑:我再次查看了您的文本文件,并发现像98.54这样的数字无法格式化为整数。因此,很明显您需要使用floatdouble而不是int来处理数组,并在fscanf()printf()中使用"%f"表示float"%lf"表示double


非常感谢您向我解释一切,谢谢!现在所有的问题对我来说都很清楚了,我知道下一步该怎么做了,谢谢! - rooooookie

0

你的代码有几个问题。

首先,你创建了一个 int 矩阵,但是看起来你正在读取浮点值。你可能想使用 double

其次,在读取双精度数时,应该使用

fscanf(file, "%lf", &some_double);  // fscanf(file, "%d", &some_int); for integers

另外,在分配矩阵时,你的第一个malloc应该传递

sizeof(double *) // or int * if you are really trying to use integers

最后,你的代码行:

mat[i][j] -= '0'

你在这里想要实现什么?你正在尝试读入的int类型数值,并减去'0'...
编辑:我还注意到你正在硬编码你要读取的行数,除非你知道文件的格式,否则我不会这样做。

其实我所有的问题都已经提到了......我觉得让所有基础知识清晰明了对我来说真的很难,但我会更加努力的,谢谢! - rooooookie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接