将双精度数组写入文件时出现问题

时间:2009-12-07 16:35:27

标签: c file-io printf

我有一个非常大的双精度数字...我试着用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]);  
}

然而,有一个问题是它将数据写入一定数量的行,之后我给出全零。例如

3.040
0.700
-2.740
0.000
0.000
0.000
0.000
0.000
0.000

我真的无法理解可能是什么问题。当数组中有值时,为什么它将所有值都写为0.000。

如果有帮助,这里是如何实现差异的。

            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 []中的所有值都已正确填充。

4 个答案:

答案 0 :(得分:4)

要打印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)非常,非常非常,很可疑 根据{{​​1}}数组中的元素数量,您不知道需要多少元素吗?请改用它。

data

答案 1 :(得分:3)

在评论后添加正式答案:

您有以下一行:


diff = (double *)malloc(fileSize);

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

您的程序可能printf而不是fprintf正常工作的原因是内存错误非常微妙。如果你开始使用你没有分配的内存,那么短时间内的事情可能没什么问题,但是当程序的另一部分非常合理地决定开始使用你已经淘气的那段内存时,它会变得混乱。

答案 2 :(得分:0)

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

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

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

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

另一方面,当您在fopen(...)函数中指定访问模式的类型时,它默认为二进制。确实应该 t 指定文本模式,如上所示。

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

答案 3 :(得分:0)

如果您只想打印第一个值,以及连续值之间的差异,为什么要打扰差异数组呢?为什么不这么简单呢?

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

正如另一个人指出的那样,你的malloc()可能是虚假的,这就是你的想法。