简体   繁体   中英

FILE * is reading zeros into a 'double' variable from input text file after reading previous entries correctly

The assignment at hand is to read values from an input file "as5input.txt" and do some basic linear calculations on the values to later write them to another output text file. Using 'fscanf()' it successfully reads the first two lines of data and then proceeds to only read zeros when it should be reading the actual values.

I have tried different formattings on fscanf and tried reading directly to see the value it was reading. I made sure there were no '\n' or ' ' characters in the input file that could cause an issue. I also tried making a new text file with the same format to make sure there were not any weird bugs with the file. However, it is still reading zeros.

I think it has something to do with reading an int and then reading a double but it does not make sense why it would be so.

This is the text file I am working with:

as5input.txt

2.0 5.0
6
1.0 2.0 4.0 8.0 16.0 31.0

And this is the program that interacts with it:

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 + %f\n", is->m, is->b);

    for (i = 0; i < is -> count; i++)
    {
        fprintf(ofp, "  x: %f   y: %f\n", 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", &m, &b, &count);

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

    instance_print(is, ofp);

    fclose(ifp);
    fclose(ofp);

    return 0;
}

This is what comes out on the output file:

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

And this is what comes out from the printf on line 51:

0.000000
0.000000
0.000000
0.000000
0.000000
0.000000

I might be missing something very simple but it is just weird that it reads the slope, intercept and count (m, b, count) correctly. Any help or advice would be greatly appreciated.

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

You're using %f as the format specifier but passing a double* , not a float* . Increase your compiler's warnings and you'll probably see a warning like this ( -Wall for gcc/clang for example):

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

The solution is to either make temp a float or use %lf as the format specifier.

Note that the %f specifier for printf is for a double , as floats are passed as doubles to functions taking a variable number of arguments. This doesn't apply to pointers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM