【问题标题】:Reading a Binary File for Floats and Putting them into an Array读取浮点数的二进制文件并将它们放入数组中
【发布时间】:2021-03-17 14:42:23
【问题描述】:

我正在读取浮点数的二进制文件并将它们存储在数组中。文件中有一组 4 字节的浮点值。但是,使用我当前的代码,数组的最后两个索引的值总是被读取为相同的值,而不是最后一个索引的实际值。 例如,我得到了

array[0] = -123456.123456
array[1] = 123456.123456
array[2] = 123456.123456

当我应该得到类似的东西时

array[0] = -123456.123456
array[1] = 123456.123456
array[2] = 654321.654321

我不确定我在阅读方面做错了什么以及为什么我得到这个输出。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <float.h>

int main(int argc, char *argv[]) {
    int fd; 
    float num; 
    size_t nr; 
    int elementnum = 0; 
    
    fd = open(argv[1], O_RDONLY); 
    nr = read(fd, &num, sizeof(float));
    
    if (fd == -1){
        printf("Error opening file");
        exit(1);
    }
    if (nr == -1){
        printf("Error reading file"); 
        exit(1); 
    }
    
    struct stat st; 
    fstat(fd, &st); 
    off_t size = st.st_size; 
    for (int j = 0; j < size/4; j++){
        elementnum++; 
    } 
    printf("number of elements: %d\n", elementnum); 
    
    float array[elementnum];
    for (int i = 0; i < elementnum; i++){
        nr = read(fd, &num, sizeof(float));
        array[i] = num; 
    }

    for (int i = 0; i < elementnum; i++){
        printf("Before Sorting: %f\n", array[i]);
    }
    close(fd);
    return 0; 
}

【问题讨论】:

  • 您能否生成输入文件的十六进制转储(例如使用xxd),编辑您的问题,并将输出发布到此处的代码块中?
  • Nitpick:我所有的计算机上的所有文件都是二进制文件。因此,除非您知道该文件中的实际格式,否则您无法阅读它。在您的情况下,它似乎与您的特定 CPU 在内存中使用的表示相同。这不是真正的便携。也就是说,是的,请提供minimal reproducible example,并且为了确保在您的读取操作中添加一些错误检查。
  • 您所做的是一种从磁盘读取浮点文件的绝妙巴洛克式的方式......不需要 stat,不需要大多数包含。我建议您删除实际上并未从磁盘读取浮点数的所有内容。您只需要在需要时打开文件、读取、调整数组大小。 就是这样。你什么都不想要了。你这样做,你会发现它工作得很好。你应该只在最简单的方法起作用后才使事情复杂化。衡量简单性的一种方法是您使用了多少不同的 I/O 函数。你需要两个。不再。想想吧。
  • 而且您也不需要任何系统特定的东西 - 不需要 POSIX 标头。使用纯 C 标准库,你需要两个头文件:stdio.hstdlib.h

标签: arrays c file


【解决方案1】:

您需要检查每次读取返回的值。由于您在打开文件后立即从文件中读取了一个字节(显然只是为了验证一次读取是否有效)并且不倒带,因此您的循环试图读取比可用值多一个的值。如果您检查最后一次迭代的读取,我怀疑您会看到它返回零。因为它返回 0,所以它不会改变 num 的值,所以 num 保留倒数第二次迭代时的值。

IOW,打开后停止读取一个字节。相反,只需 open 文件并检查 open 是否成功。然后读取直到读取返回 0 或 -1。如果read 在您预期之前返回 0,或者如果它返回 -1,则打印错误消息。

【讨论】:

    猜你喜欢
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2013-03-22
    • 1970-01-01
    • 2013-01-07
    • 2016-10-30
    • 2021-09-28
    相关资源
    最近更新 更多