【问题标题】:fscanf() not reading and crashingfscanf() 不读取并崩溃
【发布时间】:2016-04-13 13:13:15
【问题描述】:

我目前正在尝试解析 .csv 文件并将字段提取到 C 中的一些动态分配的数组中。 我尝试通过以下方式解析文件:

  1. 统计文件中的字符数
  2. 分配一个足够大的字符 * 以容纳所有字符
  3. 使用 strtok 对输入进行标记,以便将其存储在数组中

但是,这种方法并不成功,因为 .csv 包含 10^10 个字符,而我的计算机内存不足(低于 2 GB)。

但是,由于文件仅包含 10^5 行,我尝试了另一种方法:我打开 .csv 文件并逐个标记读取它,删除逗号 (,) 并在需要的地方放置空格。之后,我得到了一个新的文本文件,每行有 4 个字段:

Integer  Double      Double      Double
  Id    Latitude    Longitude    Weight

我目前正在尝试使用 fscanf 从该文件中逐行读取,然后将读取的值存储到使用 malloc 分配的 4 个数组中。代码在这里:

int main()
{
   const int m = 100000;
   FILE * gift_file = fopen("archivo.txt", "r");
   if( gift_file != NULL) fprintf(stdout, "File opened!\n");

   create_saving_list(m , gift_file);


   return 0;
}

void create_saving_list( int m, FILE * in )
{
    unsigned int index = 0;
    double * latitude = (double *)malloc(m*sizeof(double));
    if( latitude == NULL ) fprintf(stdout, "Not enoug memory - Latitude");

    double * longitude = (double *)malloc(m*sizeof(double));
    if( longitude == NULL ) fprintf(stdout, "Not enoug memory - Longitude");

    double * weight = (double *)malloc(m*sizeof(double));
    if( weight == NULL ) fprintf(stdout, "Not enoug memory - Weight");

    int * id = (int *)malloc(m*sizeof(int));
    if( id == NULL ) fprintf(stdout, "Not enough memory - ID");

    while( fscanf( in, "%d %lf %lf %lf\n", id[index], latitude[index], longitude[index], weight[index] ) > 1 )
    {
        index += 1;
    }

    /* Processing of the vector ...*/


}

我已经能够跟踪内存分配并验证它们是否正确执行。问题出在 while() 内部,因为 fscanf() 调用对我来说似乎是正确的,但它会立即导致崩溃。我尝试打印索引以查看它是否已更改,但未打印。

欢迎任何形式的帮助。

【问题讨论】:

    标签: c file csv io scanf


    【解决方案1】:

    我认为你应该在这里提供元素的地址:

    fscanf( in, "%d %lf %lf %lf\n", &id[index], &latitude[index], &longitude[index], &weight[index])
    

    它应该可以工作

    【讨论】:

      【解决方案2】:

      您需要指向 fscanf 中的整数/浮点数的指针,即

      fscanf( in, "%d %lf %lf %lf\n", &id[index], &latitude[index], &longitude[index], &weight[index] ) == 4 )
      

      还要检查它是否等于 4,因为您希望使用所有格式并为所有变量赋值

      【讨论】:

      • 有趣。那么 fscanf 返回它执行后读取的数字或值?
      • @addictedtohaskell:基本上,是的;如果在读取任何项目之前发生匹配失败,它将返回EOF
      • 我明白了,这很有用!我对此有最后一个问题。我之前是通过传递地址来阅读的,但我只检查了 while( fscanf(....) ) //我删除了 == 4 或 > 1) 循环从未结束,甚至很难我放了一个 printf("% d\n", 索引);在其中,从未打印过 index 的值。你知道为什么吗?我想知道这个!
      • 在 C/C++ 中 0 是假的,其他都是真的。 EOF 通常是一些不为零的值,即 true
      • 我明白了。我的问题已经得到解答,甚至很多人都答对了,因为您提供了有用的信息来帮助我更好地掌握 C,我会将您的答案标记为正确。谢谢。
      【解决方案3】:
      fscanf( in, "%d %lf %lf %lf\n", id[index], latitude[index], longitude[index], weight[index] ) 
      

      应该是

        fscanf( in, "%d %lf %lf %lf\n", &id[index], &latitude[index], &longitude[index], &weight[index] ) 
      

      你需要把变量的地址传给fscanf

      【讨论】:

      • 确实如此。它修复了崩溃。我明白发生了什么。我试图传递地址,但只验证 while( fscanf(...) ) (没有> 1)。循环从未结束。除了索引增量之外,我还尝试在其中放置一个 printf 语句,但它没有被打印出来。你知道为什么吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 2019-03-24
      相关资源
      最近更新 更多