简体   繁体   English

如何从C中的文件读取float

[英]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. 用C读取文件并将数据存储在数组中。 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? 我的问题是1)我不知道如何声明数组,因为我不知道文件中存在多少个数字,所以我应该以前遍历文件并计算数字吗?

2) I don't know how to judge line number as the last '\\n' in the file may exist or may not. 2)我不知道如何判断行号,因为文件中的最后一个'\\ n'是否存在。

atof (ascii to float): atof(浮动的ascii):

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

Use fscanf : 使用fscanf

The fscanf() function shall read from the named input stream. fscanf()函数应从命名的输入流中读取。 [...] 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. 1)的答案:如果您不提前知道元素的数量,如何使用原始向量无法解决的话,如何声明数组,您必须创建自己的具有增长能力的向量。

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: 您需要以下API:

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. 该API的关键成员是createVector,destroyVector和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; 在createVector中,基本上必须将所有字段都设为0。在destroyVector中,必须具有free()v;。 In addToVector, you'll have to resize() the reserved space so another new item fits: 在addToVector中,您必须resize()保留空间,以便容纳另一个新项目:

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

Now you have to call realloc() with the new size. 现在,您必须使用新的大小调用realloc()。

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. 例如,使用C ++构建STL的人员会使向量类在每次超过容量时增长到其两倍。 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. 以下代码从stdin控制台读取,以您给定的格式处理数字,然后再次打印出来,以便人们可以检查其正确性。

#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. 要获得更强大的解决方案,您必须找到每个数字开头的字符索引,并在该位置执行fscanf

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. 例如,一个简单的数字(例如“ 0.1”)需要无限个位数才能准确表示它。

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. 对于您显示的数字(小数点后仅一位数字),一个更好的主意是将每个数字乘以10,以避免浮点会导致精度损失。 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. 这将涉及编写您自己的“ ASCII到整数”转换例程,该例程将小数点假装在实际位置的右边。 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). 这也可以节省空间,因为您可以将它们存储在8位整数(字符)数组中(对于您显示的数字,其中任何数字都不大于25.6)。

Good luck with your homework! 祝您作业愉快!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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