【问题标题】:Problem writing array of doubles to a file将双精度数组写入文件的问题
【发布时间】:2009-12-07 16:35:26
【问题描述】:

我有一个非常大的双精度数字数组...我尝试使用 fprintf() 将其写入文件...我需要在每一行中写入这些数字,所以我做了这样的事情。

if((fp2 = fopen("temp", "w")) == NULL) { perror("File cannot be opened"); exit(1); }

for(int k = 0; k < j; k++ )
{
fprintf(fp2, "%0.3lf\n", diff[k]);  
}

但是,存在一个问题,即它将数据写入到一定数量的行,之后 i 给出全零。例如

3.040
0.700
-2.740
0.000
0.000
0.000
0.000
0.000
0.000

我真的不明白可能是什么问题。当数组中有值时,为什么将所有值都写为0.000。

如果有帮助,这里是 diff 的实现方式。

            diff = (double *)malloc(fileSize);

        diff[0] = data[0];


        for(j = 1; j < n; j++ )
        {
            diff[j] = data[j] - data[j-1];
        }

文件中的值存储在 data[] 中。然后我将 data[] 中相邻值的差异计算为 diff[] 并将其写回另一个文件。 fileSize 是原始文件的大小。而且我确信 diff[] 中的所有值都已正确填充。

【问题讨论】:

  • 你怎么知道有一些值?您是否在fprintf() 上使用了断点并实际检查了该数组的内容?
  • 你确定 diff 中至少有 j 个元素吗?
  • 在格式说明符中将小写“l”更改为大写“L”。
  • 您能显示声明diff 的来源吗?你能告诉我们j被赋值的来源吗?
  • 是的,我确定,我通过将 printf("%0.3lf\n", diff[k]) 写入控制台来检查它,它显示了所有值。所以我很确定数据在那里...我知道它的大小可达 j。

标签: c file-io printf


【解决方案1】:

打印double 值的正确转换说明符是%f,而不是%lf

C99 没有指定 %lf 接受什么。您的实现可能会提供%lf 作为long doubles 的扩展或其他内容,但您需要将变量的类型与转换说明符匹配。检查编译器的文档。

如果您有 long doubles,则正确的 C99 转换说明符是 %Lf


编辑,问题被编辑后

            for(j = 1; j < n; j++ )
            {
                    diff[i] = data[i] - data[i-1];
            }

循环变量是j,差异和数据的索引是i。这是复制/粘贴错误,还是您真正的问题? :)


第二次编辑

嗯...malloc(fileSize) 看起来非常、非常、很可疑。
根据data 数组中的元素数量,您不知道需要多少元素吗?改用它。

diff = malloc(number_of_elements_in_array_data * sizeof *diff);

【讨论】:

    【解决方案2】:

    在 cmets 之后添加为官方答案:

    你有以下行:

    
    diff = (double *)malloc(fileSize);
    

    请注意,当您malloc(fileSize) 时,您正在内存中分配文件大小字节。每个 double 需要 8 个字节(或多或少取决于平台),因此您的数组中将有 fileSize / 8 个元素。您确定 n 永远不会超过数组中的元素数吗?

    您的程序可能printf 而不是fprintf 下正常工作的原因是内存错误非常非常微妙。如果您开始使用尚未分配的内存,那么短期内可能还好,但当程序的另一部分非常合理地决定开始使用您已经在调皮使用的那块内存时,事情就会变得混乱。

    【讨论】:

      【解决方案3】:

      这可能是因为您将数组初始化为零,即通过memset 或类似的0.0。并且在迭代数组时,它会将偏移量中的值拉入为零(可能是您过度分配/超出估计的数组大小)。

      if((fp2 = fopen("temp", "wt")) == NULL) { perror("文件无法打开"); 退出(1); } for(int k = 0; k 0.0) fprintf(fp2, "%0.3lf\n", diff[k]); }

      我添加了一个额外的逻辑来检查数组中指定偏移量中的值是否大于零,并将其放入文件中。

      另外,当你在fopen(...)函数中指定访问模式的类型时,它默认为二进制。确实应该t来指定文本模式,如上图。

      希望这会有所帮助, 最好的祝福, 汤姆。

      【讨论】:

      • fopen() 默认为文本模式。 mode 参数中的“t”是一个(冗余)编译器扩展——C 标准无法识别它。
      • @pmg:我的错!感谢您的提醒!我是老派......:P
      【解决方案4】:

      如果您只想打印第一个值,以及连续值之间的差异,为什么还要使用差异数组?为什么不以简单的方式来做呢?

      fprintf(fp2, "%Lf\n", data[0]);
      for(j = 1; j < n; j++ )
      {
        fprintf(fp2, "%Lf\n", data[j] - data[j-1]);
      }
      

      正如其他人指出的那样,您的 malloc() 可能是伪造的,这就是您的问题所在。

      【讨论】:

        猜你喜欢
        • 2019-12-05
        • 2013-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多