当前位置:首页 > > 充电吧
[导读]在另一个贴子中,我与一些朋友对 getc 展开了一些讨论. 由于觉得楼主最终未能明白我的意思,所以我把我个人的看法总结出来,写在这里.我不太擅长说明,但已经尽力了. 任何人转本贴, 请务必把本人的名字

在另一个贴子中,我与一些朋友对 getc 展开了一些讨论. 由于觉得楼主最终未能明白
我的意思,所以我把我个人的看法总结出来,写在这里.我不太擅长说明,但已经尽力了.
任何人转本贴, 请务必把本人的名字写在显眼的位置.  


约定编译器为 gcc2/x86:
所以 char, unsigned char 为 8 位, int 为 32 位


(1) 字节的读取

在正常的情况下, getc 以 unsigned char 的方式读取文件流, 扩张为一个整数,并返
回. 换言之, getc 从文件流中取一个字节, 并加上24个零,成为一个小于256的整数,
然后返回.

int c;
while ((c = fgetc (rfp))!= -1) // -1就是 EOF
fputc (c, wfp);

上面 fputc 中的 c 虽然是整数, 但在 fputc 将其写入文件流之前, 又把整数的高24位
去掉了, 因此 fgetc, putc 配合能够实现文件复制. 到目前为止, 把 c 定义为
char仍然是可行的, 但下面我们将看到,把 c 定义为 int 是为正确判段文件是否结束.

(2) 判断文件结束.

多数人认为文件中有一个EOF,用于表示文件的结尾. 但这个观点实际上是错误的,在文
件所包含的数据中,并没有什么文件结束符. 对getc 而言, 如果不能从文件中读取,
则返回一个整数 -1,这就是所谓的EOF. 返回 EOF 无非是出现了两种情况,一是文件已
经读完; 二是文件读取出错,反正是读不下去了.

请注意: 在正常读取的情况下, 返回的整数均小于256, 即0x0~0xFF. 而读不出返回的
是 0xFFFFFFFF. 但, 假如你用fputc把 0xFFFFFFFF 往文件里头写, 高24位被屏蔽,写入的将
是 0xFF. // lixforalpha 请注意这一点

(3) 0xFF 会使我们混淆吗?

不会, 前提是, 接收返回值的 c 要按原型定义为 int.

如果下一个读取的字符将为 0xFF, 则

int c;
c = fgetc (rfp); // c = 0x000000FF;
if (c != -1)    // 当然不等, -1 是 0xFFFFFFFF
fputc (wfp);   // 噢, OXFF 复制成功.

字符0xFF, 其本身并不是EOF.

(4) 将 c 定义 char

假定下一个读取的字符为 0xFF 则

char c;
c = fgetc (rfp); // fgetc(rfp)的值为 0x000000FF, 暗中降为字节, c = 0xFF
if (c != -1)    // 字符与整数比较? c 被带符号(signed)扩展为0xFFFFFFFF, 喔噢,
条件成立,文件复制提前退出.

while ((c=fgetc(rfp))!=EOF) 中的判别条件成立, 文件复制结束! 意外中止.

(5) 将 c 定义为 unsigned char;

当读到文件末尾, 返回 EOF 也就是 -1 时,

unsigned char c;
c = fgetc (rfp); // fgetc (rfp)的值为EOF,即-1,即0xFFFFFFFF, 降格为字节, c=0xFF
if ( c!= -1)  // c 被扩展为 0x000000FF, 永远不回等于 0xFFFFFFFF

所以这次虽然能正确复制 0xFF, 但却不能判断文件结束. 事实上,在 c 为 uchar 时,
c != -1 是永远成立的, 一个高质量的编译器, 比如 gcc会在编译时指出这一点.

(6) 为何需要feof?
FILE *fp;
fp 指向一个很复杂的数据结构, feof 是通过这个结构中的标志来判断文件是否结束的.
如果文件用 fgetc 读取, 刚好把最后一个字符读出时, fp 中的EOF标志不会打开,这时
用feof判断,将会得到文件尚未结束的结论.

fgetc 返回 -1 时, 我们仍无法确信文件已经结束, 因为可能是读取错误! 这时我们
需要 feof 和 ferror.

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在C语言编程中,结构体内存对齐是一个容易被忽视却影响深远的关键问题。它不仅关乎程序性能,更直接影响到内存占用效率,尤其在嵌入式系统等资源受限环境中显得尤为重要。本文将深入探讨结构体内存对齐的原理,并分享手动调整与编译器优...

关键字: C语言 内存对齐 编译器

编译器不仅是连接硬件与软件的桥梁,还直接影响MCU的性能优化与功能安全。面对汽车行业对高可靠性、低功耗和高算力的需求,编译器需在确保ASIL-D等严格标准的同时,最大化发挥RISC-V芯片的潜力。

关键字: 车规MCU RISC-V 编译器 HighTec

国内电子信息产业内的厂商正在全球嵌入式系统的发展浪潮中扮演着越来越重要的角色,但随之而来的是国内嵌入式系统和相关芯片企业在出海时也面临越来越多的合规要求,尤其是在保障用户、设备和周边人与物安全的功能安全领域内的合规要求。...

关键字: 嵌入式系统 智能网联 编译器

【2025年4月11日, 德国慕尼黑讯】全球功率系统和物联网领域的半导体领导者英飞凌科技股份公司(FSE代码:IFX / OTCQX代码:IFNNY)推出用于AURIX™、TRAVEO™和PSOC™的可扩展软件包产品组合...

关键字: PSOC 物联网 编译器

瑞典乌普萨拉,2025年3月11日 — 全球领先的嵌入式系统开发软件解决方案供应商IAR在德国纽伦堡举办的embedded world 2025展会上重磅发布全新云端平台。该平台为嵌入式软件开发人员提供前所未有的自由度与...

关键字: 编译器 嵌入式 RISC-V

该统一解决方案为Microchip编译器产品线提供灵活且经济高效的许可选项

关键字: 编译器 嵌入式

当安全标准相互契合:意法半导体 (ST) Stellar MCU取得了风险管理安全标准等级最高的ISO 26262 ASIL D 级认证,现在更有达到同等安全级别的 HighTec Rust 编译器的加持

关键字: 微控制器 编译器

在STM32的开发过程中,开发者可能会遇到各种编译错误,其中“Program file does not exist”是一个较为常见且可能由多种原因引起的错误。这个错误通常意味着编译器在预期的路径下没有找到可执行文件(如...

关键字: STM32 编译器

基于ARM内核的芯片在我们的世界中无处不在,从简单的MCU到高端的应用处理器,各行各业中都有它们的身影。 如今ARM生态系统非常繁荣,在这繁荣的背后编译器的作用功不可没。

关键字: ARM 编译器

台湾新竹-2024 年 11 月 5 日-新唐科技正式推出免费版 Arm® Keil® MDK Nuvoton Edition,成为全球首家提供 Keil MDK 完整版的公司。此专业工具适用于开发基于Arm Corte...

关键字: 编译器 微控制器 嵌入式
关闭