Проблема записи массива двойников в файл - PullRequest
1 голос
/ 07 декабря 2009

у меня действительно большой массив чисел с двойной точностью ... я пытался записать его в файл, используя 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, если это поможет.

            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 ]

4 голосов
/ 07 декабря 2009

Правильный спецификатор преобразования для вывода значения 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, индексы для diff и data i. Была ли это ошибка копирования / вставки или это ваша настоящая проблема? :)


2-е редактирование

Хммм ... это malloc(fileSize) выглядит очень, очень , подозрительно.
Разве вы не знаете, сколько элементов вам нужно, исходя из количества элементов в массиве data? Используйте это вместо этого.

diff = malloc(number_of_elements_in_array_data * sizeof *diff);
3 голосов
/ 07 декабря 2009

Добавление в качестве официального ответа после комментариев:

У вас есть следующая строка:


diff = (double *)malloc(fileSize);

Обратите внимание, что когда вы malloc(fileSize), вы выделяете fileSize байтов в памяти. Каждый дубль занимает 8 байтов (более или менее в зависимости от платформы), поэтому в вашем массиве будут элементы fileSize / 8. Вы уверены, что n никогда не превышает количество элементов в вашем массиве?

Причина, по которой ваша программа может корректно работать с printf, а не с fprintf, заключается в том, что ошибки памяти очень и очень тонкие. Если вы начнете использовать память, которую вы не распределили, то в течение короткого периода времени все может быть в порядке, но обанкротиться, когда другая часть программы вполне законно решит начать использовать ту часть памяти, которую вы уже излишне используете.

0 голосов
/ 07 декабря 2009

Если вы просто хотите напечатать первое значение и различия между последовательными значениями, зачем беспокоиться о массиве различий? Почему бы не сделать это простым способом?

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

Как заметил другой парень, ваш malloc (), вероятно, фальшивый, и это то, что вас преследует.

0 голосов
/ 07 декабря 2009

Это может быть тот факт, что массив инициализирован в ноль, т.е. 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 , чтобы указать текстовый режим, как показано выше.

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

...