简体   繁体   中英

How to read float from a file in C

Suppose the file is organized in this way:

1.2 # 3.4 # 4.0

2.3 # 2.3 # 1.2

Read the file in C and store data in an array. Meanwhile, you should judge how many lines there are.

My problem is 1) I don't know how to declare the array as I don't know how many numbers exist in the file, so should I go over the file previously and count the number?

2) I don't know how to judge line number as the last '\\n' in the file may exist or may not.

atof (ascii to float):

http://en.wikipedia.org/wiki/Atof

Use fscanf :

The fscanf() function shall read from the named input stream. [...] Each function reads bytes, interprets them according to a format, and stores the results in its arguments. Each expects, as arguments, a control string format described below, and a set of pointer arguments indicating where the converted input should be stored.

The answer to 1) How to declare the array if you don't know the number of elements in advance, is unsolvable with primitive vectors, you'll have to create your own growing-capable vector.

typedef struct {
    double * v;
    unsigned int size;
} Vector;

This struct is the basis of the new data type. You'll need an API such as:

Vector createVector();

void addToVector(Vector *v, double x);
double getFromVector(Vector *v, unsigned int pos);
void modifyInVector(Vector *v, unsigned int pos, double x);
unsigned int sizeOfVector(Vector * v);

void destroyVector(Vector *v);

The key members of the API are createVector, destroyVector and addToVector. Since this is probably homework, I won't resolve this to you.

In createVector, you basically have to put all fields to 0. In destroyVector, you have to free() v; In addToVector, you'll have to resize() the reserved space so another new item fits:

size_t newSize = ( v->size +1 ) * sizeof( double );

Now you have to call realloc() with the new size.

And that's basically all. If you want better performance, you can introduce also the capacity of the vector, so you don't have to make it grow each time you add a new value. For example, the people that built the STL in C++ make the vector class grow to its double each time the capacity is exceeded. But, anyway, that's another story.

The following code reads from the stdin console, processes the numbers in the format you gave and prints them out again so one can check for correctness.

#include <stdio.h>

int main(int ac, char *av[])
{
    float a, b, c;
    scanf("%f # %f # %f", &a, &b, &c);
    printf("%f # %f # %f", a, b, c);
    printf("\n");
}

Albeit this code works, it is not very robust. It requires the EXACT sequence ' # ' of characters between numbers and there is nothing but a newline allowed after the last number in a row.

For a more robust solution you would have to find the character index of the start of each number and do a fscanf on that location.

Floating point has precision loss for decimal fractions. For example, a simple number like "0.1" needs an infinite number of bits to represent it accurately.

For the numbers you've shown (only one digit after the decimal point), a better idea would be to multiply each number by 10 to avoid the precision loss that floating point would cause. This would involve writing your own "ASCII to integer" conversion routine that pretends the decimal point is one place to the right of where it actually is. It would also save space, as (for the numbers you've shown, where no number is greater than 25.6) you could store them in an array of 8-bit integers (chars).

Good luck with your homework!

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