FILE * считывает нули в переменную ‘double’ из входного текстового файла после правильного чтения предыдущих записей

#c #file #input #file-io

#c #файл #ввод #file-io

Вопрос:

Задача состоит в том, чтобы считывать значения из входного файла «as5input.txt » и выполните некоторые базовые линейные вычисления для значений, чтобы позже записать их в другой выходной текстовый файл. Используя ‘fscanf ()’, он успешно считывает первые две строки данных, а затем продолжает считывать нули только тогда, когда он должен считывать фактические значения.

Я пробовал разные форматирования в fscanf и пытался читать напрямую, чтобы увидеть значение, которое он считывал. Я убедился, что во входном файле нет символов ‘ n’ или ‘ ‘, которые могли бы вызвать проблему. Я также попытался создать новый текстовый файл с тем же форматом, чтобы убедиться, что с файлом не было никаких странных ошибок. Тем не менее, он по-прежнему считывает нули.

Я думаю, что это как-то связано с чтением int, а затем с чтением double, но не имеет смысла, почему это было бы так.

Это текстовый файл, с которым я работаю:

as5input.txt

 2.0 5.0
6
1.0 2.0 4.0 8.0 16.0 31.0

 

И это программа, которая взаимодействует с ней:

as5.c

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct instance_struct
{
    int count;
    float m, b;
    double * x, * y;
};

typedef struct instance_struct instance;

void instance_print(instance *is, FILE * ofp)
{
    int i;

    fprintf(ofp, "  y = %f x   %fn", is->m, is->b);

    for (i = 0; i < is -> count; i  )
    {
        fprintf(ofp, "  x: %f   y: %fn", is->x[i], is->y[i]);
    }
}

instance * make_instance(int count, float m, float b) {
    instance * is = (instance *)malloc(sizeof(instance));
    is -> m = m;
    is -> b = b;
    is -> count = count;
    is -> x = (double *)malloc(sizeof(double) * count);
    is -> y = (double *)malloc(sizeof(double) * count);
    return is;
}

int main(void)
{
    int i, count;
    float m, b;

    FILE *ifp, *ofp;
    ifp = fopen("as5input.txt", "r");
    ofp = fopen("out.txt", "w");

    fscanf(ifp, "%f %f %d", amp;m, amp;b, amp;count);

    double temp;
    instance * is = make_instance(count, m, b);
    for (i = 0; i < count; i  ) {
        fscanf(ifp, "%f", amp;temp);
        printf("%fn", temp);
        is -> x[i] = temp;
        is -> y[i] = m * temp   b;
    }

    instance_print(is, ofp);

    fclose(ifp);
    fclose(ofp);

    return 0;
}
 

Это то, что отображается в выходном файле:

out.txt

   y = 2.000000 x   5.000000
  x: 0.000000   y: 5.000000
  x: 0.000000   y: 5.000000
  x: 0.000000   y: 5.000000
  x: 0.000000   y: 5.000000
  x: 0.000000   y: 5.000000
  x: 0.000000   y: 5.000000
 

И это то, что выходит из printf в строке 51:

 0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
 

Возможно, я упускаю что-то очень простое, но просто странно, что он правильно считывает наклон, перехват и количество (m, b, count). Любая помощь или совет будут высоко оценены.

Ответ №1:

 double temp;
instance * is = make_instance(count, m, b);
for (i = 0; i < count; i  ) {
    fscanf(ifp, "%f", amp;temp);
    ...
}
 

Вы используете %f в качестве спецификатора формата, но передаете a double* , а не a float* . Увеличьте предупреждения вашего компилятора, и вы, вероятно, увидите предупреждение, подобное этому ( -Wall например, для gcc / clang):

 <source>:50:27: warning: format specifies type 'float *' but the argument has type 'double *' [-Wformat]
        fscanf(ifp, "%f", amp;temp);
                     ~~   ^~~~~
                     %lf
 

Решение состоит в том, чтобы либо создать temp float , либо использовать %lf в качестве спецификатора формата.

Обратите внимание, что %f спецификатор for printf для a double , as floats передаются как doubles функции, принимающие переменное количество аргументов. Это не относится к указателям.

Комментарии:

1. Спасибо за ответ promt! Ценю это