Windows 下EOF 和 Linux 下EOF的区别

本文探讨了Windows和Linux系统中EOF(文件结束)的区别,包括阻塞式和非阻塞式的不同处理方式,以及如何在两种系统下正确地使用EOF指令。

由于C++作业在Windows下 用VS写的,提交作业要用Linux测试,出现了一些问题。

经过查阅,发现Windows 和 Linux下EOF指令的一些区别,在这里记录一下,如有理解不当的地方请指正哈。


主要参考博主爱若一生的文章http://blog.youkuaiyun.com/cwj649956781/article/details/7327937


EOF是end of file的缩写,表示"文字流"(stream)的结尾。这里的"文字流",可以是文件(file),也可以是标准输入(stdin)。当从键盘上输入一串字符并按回车后,这些字符会首先被送到输入缓冲区中存储。每当按下回车键后,cin.get()    就会检测输入缓冲区中是否有了可读的数据。cin.get()    还会对键盘上是否有作为流结束标志的    Ctrl+Z    或者    Ctrl+D    键作出检查。

检测EOF的方式有两种:阻塞式和非阻塞式。


阻塞式只在按下回车后才检测之前是否有Ctrl + Z 是否按下(Windows一般采用阻塞式,Ctrl + Z表示EOF)。如果先输入了一些字符,没有回车换行重新输入Ctrl+Z,那么输入缓冲区由于存在其他的可读数据,从而不会检测到Ctrl+Z(因为有要读的数据,所以不能认为到了文字流的末尾)。所以,若想在windows下正确执行EOF,必须新的一行只输入Ctrl+ Z指令。


Ctrl+Z产生的不是一个普通的ASCII码值,也就是说它产生的不是一个字符,所以不会跟其它从键盘上输入的字符一样能够存放在输入缓冲区。   


例如,从键盘上输入abcd^z  ,再回车之后在Windows系统上是这样处理的:由于回车的作用,前面的  abcd    等字符被送到输入缓冲区(注意:上面说过了,^z不会产生字符,所以更不会存储到输入缓冲区,缓冲区中没有   ^z   的存在)。这时,cin.get()    检测到输入缓冲区中已经有数据存在(因此不再检查是否有    ^z    的输入),于是从缓冲中读取相应的数据。如果都读取完了,则输入缓冲区重新变为空,cin.get()    等待新的输入。可见,尽管有    ^z    按下,但是由于在此之前还有其它输入(abcd),所以流也不会结束。


非阻塞式 是指按下   Ctrl 的组合键  之后立即响应的方式(Unix / Linux 一般采用非阻塞式, Ctrl + D 表示EOF)。如果先输入了一些字符,未换行直接输入 Ctrl + D,需要再次输入Ctrl + D 才可以正常EOF。当终端有字符输入时,Ctrl+D产生的EOF相当于结束本行的输入,将引起getchar()新一轮的输入;当终端没有字符输入或者可以说当getchar()读取新的一次输入时,输入Ctrl+D,此时产生的EOF相当于文件结束符,程序将结束getchar()的执行。





<think>我们正在讨论C语言中的两个概念:EOFNULL。它们看似相似(都是宏定义),但用途完全不同。 1. **EOF (End Of File)**: - 定义在<stdio.h>中,通常为-1(但标准仅要求是负整数)。 - 用于表示文件结束或输入流结束的条件。 - 常见于文件读取函数(如getchar, fgetc, scanf等)的返回值。 2. **NULL**: - 定义在<stddef.h>、<stdio.h>、<stdlib.h>等多个头文件中,通常为(void*)0(空指针常量)。 - 用于表示指针不指向任何有效对象。 - 常见于指针初始化或函数返回空指针时。 ### 代码示例说明 #### 示例1:EOF的使用(读取字符直到文件结束) ```c #include <stdio.h> int main() { int c; // 注意:必须用int,因为EOF可能是负数,而char可能是无符号的 while ((c = getchar()) != EOF) { putchar(c); } return 0; } ``` **关键点**: - `getchar()`返回`int`类型,因为除了返回所有可能的字符(通常0~255)外,还要返回EOF(-1)。 - 当从键盘输入时,在Unix/Linux下按Ctrl+D,Windows下按Ctrl+Z,然后回车,可以产生EOF。 #### 示例2:NULL的使用(指针初始化) ```c #include <stdio.h> #include <stdlib.h> int main() { int *ptr = NULL; // 初始化为空指针 ptr = (int*)malloc(sizeof(int) * 10); if (ptr == NULL) { fprintf(stderr, "Memory allocation failed\n"); return 1; } // 使用分配的内存... free(ptr); ptr = NULL; // 避免悬垂指针 return 0; } ``` **关键点**: - 使用NULL初始化指针,避免野指针。 - 检查内存分配是否成功(malloc失败时返回NULL)。 - 释放内存后将指针置为NULL,避免再次使用已释放的内存。 ### 对比总结表 | 特性 | EOF | NULL | |--------------|------------------------------|--------------------------| | 类型 | `int`(通常是-1) | 空指针常量(通常是0) | | 用途 | 表示输入/文件结束 | 表示指针不指向任何对象 | | 定义位置 | <stdio.h> | 多个头文件(如<stdlib.h>)| | 常见上下文 | 输入函数(getchar, scanf等) | 指针赋值检查 | ### 常见错误 1. **混淆类型**: - 错误:`char c; while((c = getchar()) != EOF) ...` - 原因:如果char是无符号的,EOF(-1)会被转换为255,导致永远不会等于EOF;如果char是有符号的,当读到0xFF(即255)时,转换为char可能是-1,会被误认为是EOF。 - 正确:使用`int`类型。 2. **误用NULL**: - 错误:`int *p = EOF;` (类型不匹配,EOF是整数,而指针应当用NULL) - 正确:`int *p = NULL;` §§相关问题§§: 1. 为什么`getchar()`返回int而不是char? 2. 在C语言中,如何检查一个文件指针是否到达文件末尾? 3. 空指针未初始化的指针有什么区别? 4. 除了EOFNULL,C语言中还有哪些重要的宏? </think>### EOF NULL 在 C 语言中的区别 #### 核心区别: | 特性 | EOF | NULL | |--------------|------------------------------------|--------------------------| | **用途** | 表示文件结束或输入流结束 | 表示空指针(不指向任何内存地址) | | **类型** | `int` 类型(通常是 `-1`) | 指针类型(通常是 `(void*)0`) | | **定义位置** | `<stdio.h>` 头文件 | `<stddef.h>` 或 `<stdio.h>` | | **常见场景** | 文件读取函数返回值(如 `getchar()`)| 指针初始化或函数返回值 | --- ### 详细解释与代码示例 #### 1. EOF (End Of File) - 用于表示输入流结束的特殊整数值(通常是 `-1`) - 常见于文件/输入读取函数的返回值 ```c #include <stdio.h> int main() { int c; // 从标准输入读取字符直到EOF while ((c = getchar()) != EOF) { putchar(c); } printf("\nReached end of input\n"); return 0; } ``` **运行说明**: 1. 程序会持续读取用户输入的字符 2. 在 Linux/macOS 按 `Ctrl+D` 或在 Windows 按 `Ctrl+Z` 后回车发送 EOF 3. 此时 `getchar()` 返回 EOF,循环结束 --- #### 2. NULL - 空指针常量,表示指针不指向任何有效内存地址 - 用于指针初始化、错误检查等场景 ```c #include <stdio.h> #include <stdlib.h> int main() { FILE *filePtr = NULL; // 尝试打开文件 filePtr = fopen("example.txt", "r"); // 检查指针是否为空(文件是否成功打开) if (filePtr == NULL) { perror("Error opening file"); return 1; } // 文件操作... fclose(filePtr); return 0; } ``` **关键点**: 1. 初始化为 `NULL` 避免野指针 2. 检查 `fopen()` 返回是否为 `NULL` 判断操作是否成功 3. 安全的内存地址表示(通常等于地址 0) --- ### 常见错误对比 | 错误场景 | EOF 相关错误 | NULL 相关错误 | |----------------------|---------------------------------------|-------------------------------------| | **典型错误** | `char c = getchar()`(应使用 `int`) | 未初始化指针(应设为 `NULL`) | | **后果** | 无法正确处理 EOF(`char` 无法存 `-1`)| 段错误(访问无效内存) | | **正确做法** | 使用 `int` 接收 IO 函数返回值 | 指针初始化为 `NULL` 并检查 |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值