使用fread将文件内容读入结构 [英] Using fread to read the contents of a file into a structure

查看:68
本文介绍了使用fread将文件内容读入结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在"Unix环境中的高级编程"一书中,有一部分(第251页的8.14节)中,作者向我们展示了"acct"结构的定义(用于存储会计记录信息).然后,他显示了一个程序,在该程序中,他将文件中的会计数据读入struct(其关键部分是)中:

In the "Advanced Programming in the Unix Environment" book there's a part (ch 8.14, page 251) in which the author shows us the definition of the "acct" struct (used to store accounting records info). He then shows a program in which he reads the accounting data from a file into the struct (the key part of which is):

fread (&acdata, sizeof(acdata), 1, fp)

我遇到的麻烦是,我听说C编译器有时会在内存中重新排列结构的元素,以便更好地利用空间(由于对齐问题).因此,如果该代码只是获取了文件的所有内容并将其粘贴到acdata中(并且文件的内容被安排为与struct定义中指定的顺序相匹配),则如果struct的某些元素已被移动,那么如果我在代码中引用它们,则可能无法达到预期的效果(因为文件中的数据没有按照结构体在内存中的方式进行重新排列).

The trouble I'm having is that I've heard that C compilers will sometimes rearrange the elements of a struct in memory in order to better utilize space (due to alignment issues). So, if this code is just taking all of the content of the file and sticking it into acdata (and the contents of the file are arranged to match the ordering specified in the struct definition) if some of the elements of struct have been moved, then if I refer to them in code, I may not be getting what I expected (since the data in the file did not get rearranged the way the struct did in memory).

我想念什么(由于我得到的东西似乎不可靠)?

What am I missing (because from what I'm getting this doesn't seem reliable)?

感谢您的帮助(如果我在程序上做错了事,我深表歉意-这是我第一次发布)

Thanks for your help (my apologies if I've done something wrong procedurally - this is my first time posting)

推荐答案

您的程序将稳定.

您的问题已经引发了您实际上并未要求的可移植性建议的篝火晚会.您似乎要问的问题是此代码模式和程序稳定吗?".答案是 是.

Your question has touched off a bonfire of portability recommendations that you didn't actually ask for. The question you seemed to be asking is "is this code pattern and my program stable?". And the answer to that is yes.

您的结构不会重新排序.C99特别禁止重新排列结构成员. 1

You structure will not be reordered. C99 specifically prohibits rearranging the structure members.1

此外,布局和对齐方式不取决于优化级别.如果这样做的话,所有程序,所有库例程,内核,所有内核接口等都必须完全以相同的优化级别构建.

Also, the layout and alignment do not depend on optimization level. If they did, all programs would have to be entirely built with the same optimization level, as well as all library routines, the kernel, all kernel interfaces, etc.

用户还必须永远跟踪上面列出的所有已编译为系统一部分的接口的优化级别.

Users would also have to track, forever, the optimization level of every one of those interfaces listed above that ever had been compiled as part of the system.

内存对齐规则实际上是隐藏的 ABI .如果不添加非常专业的定义上很少使用的编译器标志,则无法更改它们.它们往往可以在不同的编译器上正常工作.(否则,上面确定的系统的每个元素也都必须由同一编译器编译,否则就没有用.支持给定系统的每个编译器都使用完全相同的对齐规则.什么都行不通,否则,通常会在给定OS的编译器配置中内置更改对齐策略的编译器标志.

The memory alignment rules are really a kind of hidden ABI. They can't change without adding very specialized and by definition rarely-used compiler flags. They tend to work just fine over different compilers. (Otherwise, every element of a system identified above would ALSO have to be compiled by the same compiler, or be useless. Every compiler that supports a given system uses the exact same alignment rules. Nothing would work, otherwise.) The compiler flags that change alignment policies are usually intended to be built into the compiler configuration for a given OS.

现在,虽然您的二进制文件布局非常合理,但 有点过时了.它具有某些缺点.虽然这些都不是阻止程序的使用,而且通常都不值得重写应用程序,但它们包括:

Now, your binary file layout, while perfectly reasonable, is a bit old-school. It has certain drawbacks. While none of these are show-stoppers and none are generally worth rewriting an app, they include:

  • 调试二进制文件很困难
  • 它们确实以单字节顺序和单个对齐策略锁定.在(很可能,越来越不可能)需要移植到新体系结构的情况下,最终可能需要使用memcpy(3)来解压缩记录.不是世界末日.
  • 它们不是结构化的.诸如YAML甚至是XML之类的东西都是自解析的,因此在文件中读取它变得容易得多,并且可以使用工具来完成某些类型的文件操作.更重要的是,文件格式本身变得更加灵活.但是,在C和C ++中,利用自动解析对象的能力受到限制.

据我了解Paxdiablo的要求,他希望我同意存在编译器选项和编译指示,如果使用这些选项和编译指示,它们会更改对齐规则.这是真的.显然,这些选项仅出于特定原因使用.

As I understand Paxdiablo's request, he would like me to agree that there exist compiler options and pragmas that, if used, will alter the alignment rules. That's true. Obviously these options are used only for specific reasons.

1. C99 6.7.2.1(13) 在结构对象中,非位字段成员以及其中位字段的单位驻留的地址按照它们的声明顺序增加.

这篇关于使用fread将文件内容读入结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆