开发者

How to read float from a file in C

开发者 https://www.devze.com 2023-03-03 12:58 出处:网络
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.开发者_如何学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.开发者_如何学C

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.


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.


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 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!

0

精彩评论

暂无评论...
验证码 换一张
取 消