tags:

views:

117

answers:

4

i have a really big array of numbers with double precision...i tried to write it into a file using fprintf()...i need to write these numbers one in each line so i have done something like this.

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]); 
}

However, there is a problem that it writes the data upto certain number of lines after which i gives all zeroes. for example

3.040
0.700
-2.740
0.000
0.000
0.000
0.000
0.000
0.000

i really can't understand what could be the problem. why does it write all values as 0.000 when there are values in the array.

here is how diff was implemented if it helps.

            diff = (double *)malloc(fileSize);

  diff[0] = data[0];


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

the values from a file were stored in data[]. i then calculated the difference of adjacent values in data[] into diff[] and write it back into another file. fileSize was the size of the original file. and i know for sure that all the values in diff[] are populated correctly.

A: 

It could be the fact that you have the array initialized to zero i.e. 0.0 via memset or similar. And when iterating the array, it pulled in the value in the offset which is zero (it could be you over-allocated/over estimated size of an array).

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]);      
}

I have added an extra logic to check if the value in the specified offset to the array is greater than zero, to put it into the file.

Another thing, when you specify the type of access mode in the fopen(...) function, it defaults to binary. Really it should be t to specify text mode, as shown above.

Hope this helps, Best regards, Tom.

tommieb75
fopen() defaults to text mode. The 't' in the mode argument is a (redundant) compiler extension -- it is not recognized by the C Standard.
pmg
@pmg: My bad! Thanks for the heads up! I'm old school... :P
tommieb75
+4  A: 

The correct conversion specifier to print a double value is %f, not %lf.

C99 does not specify what %lf accepts. Your implementation may provide %lf as an extension for long doubles or something, but you need to match the type of the variable with the conversion specifier. Check the documentation for your compiler.

If you have long doubles the correct C99 conversion specifier is %Lf.


Edit, after question was edited

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

The loop variable is j, the indexes for diff and data are i. Was this a copy/paste error, or is it your real problem? :)


2nd edit

Hmmm ... that malloc(fileSize) looks very, very, fishy.
Don't you know how many elements you need, based on the number of elements in the data array? Use that instead.

diff = malloc(number_of_elements_in_array_data * sizeof *diff);
pmg
yeah it was a copy paste thing, i've corrected that.
sfactor
+2  A: 

Adding as an official answer after the comments:

You have the following line:


diff = (double *)malloc(fileSize);

Note that when you malloc(fileSize) you are allocating fileSize bytes in memory. Each double takes 8 bytes (more or less depending on platform) so you will have fileSize / 8 elements in your array. Are you SURE that n never exceeds the number of elements in your array?

The reason why your program may work correctly with printf and not with fprintf is that memory bugs are very very subtle. If you start using memory that you haven't allocated then things may be fine for a short period but go haywire when another part of the program quite legitimately decides to start using that piece of memory you're naughtily using already.

PP
A: 

If you just want to print the first value, and the differences between successive values, Why bother with the difference array? Why not do it the easy way?

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

As the other guy pointed out, your malloc() is probably bogus, and that's what's h0zing you.

John R. Strohm