
根据标题,我试图了解Ctrl + D / Ctrl + Z在一个while循环中的确切行为(我需要使用)。 我正在testing的代码如下:
#include <stdio.h> #include <stdlib.h> int main() { char str[80]; while(printf("Insert string: ") && gets(str) != NulL) { puts(str); } return 0; }
如果我的input只是一个Ctrl + D (或在windows上Ctrl + Z ) gets返回NulL,程序正常退出。 不清楚的情况是,当我插入像house^D^D (Unix)或house^Z^Zn (windows)的东西。
在第一种情况下,我的解释是getchar (或gets函数内的类似内容)等待read()以获取input,第一个Ctrl + D刷新非空的缓冲区(因此不是EOF),然后第二次读取()被称为EOF被触发。
在第二种情况下,我注意到,第一个Ctrl + Z被插入到缓冲区中,而后面的所有内容都被忽略。 因此,我的理解是第一次读取()调用插入的house^Z和丢弃一切返回5(读取的字符数)。 (我说5,否则我认为一个简单的Ctrl + Z应该返回1而不触发EOF)。 然后程序等待来自用户的更多input,因此再次进行read()调用。
我想知道我的工作方式是正确还是错误,哪一部分只是执行依赖(如果有的话)。
此外,我注意到在Unix和windows中,即使在EOF被触发后,它在下面的gets()调用中似乎重置为false,我不明白为什么发生这种情况以及代码的哪一行。
奇怪的成员函数声明的错误
创build父级pipe理的两个subprocess
多核心架构上的multithreading
如何将hex字符转换为4位二进制表示?
Directory.Getfiles不返回文件
我真的很感激任何forms的帮助。
(12/20/2016)为了避免混淆,我大量编辑了我的问题
CMake为Tesseract和OpenCV
文件夹更衣室在C#
如何确定哪个windows Communication Foundation Service使用给定的端口?
如何以编程方式检测PC是否具有USB3function?
不间断地执行Cpp linux代码
CTRL-D和CTRL-Z“文件末尾”指示器分别在Unix和windows系统上有相似的用途,但实现方式相当不同。
在Unix系统上(包括像linux这样的Unix克隆),CTRL-D虽然被正式描述为文件结束字符,但实际上却是一个分隔符。 它几乎与用于分隔行的行尾字符(通常是回车符或CTRL-M)完全相同。 这两个字符都告诉 *** 作系统输入行已经完成,并使程序可用。 唯一的区别是,在行结束字符处,换行(CTRL-J)字符被插入到输入缓冲区的末尾以标记行的末尾,而在文件结束字符处不插入任何内容。
这意味着当你在Unix上输入house^D^D时, read系统调用将首先返回一个长度为5的缓冲区,其中包含5个字符。 当read被再次调用以获得更多的输入时,它将返回长度为0的缓冲区,其中没有字符。 由于在正常文件上读取的零长度表明已到达文件末尾,因此gets库函数也将其解释为文件结尾并停止读取输入。 然而,由于它用5个字符填充了缓冲区,所以它不返回NulL来表明它到达了文件的结尾。 而且由于它实际上并没有真正达到文件结尾,因为终端设备实际上不是文件,所以进一步的调用将进一步调用read ,这将返回用户输入的后续字符。
在windows上,CTRL-Z的处理方式大不相同。 最大的区别在于它没有被 *** 作系统专门处理。 当你在windows上输入house^Z^Z^M ,只有回车符给予特殊处理。 就像在Unix上一样,回车使得输入的行对程序可用,但是在这种情况下,回车和换行被添加到缓冲区以标记行的结尾。 所以结果是Readfile函数返回一个9字节长的缓冲区,其中包含9个字符house^Z^Z^M^J
它实际上是程序本身,特别是处理CTRL-Z的C运行库。 在Microsoft C运行时库的情况下,当它看到Readfile返回的缓冲区中的CTRL-Z字符时,它会将其视为文件结束标记,并忽略其后的所有内容。 使用前面段落中的例子,最后调用Readfile来获得更多的输入,因为从控制台(或其他设备)读取时看不到CTRL-Z字符的事实,而且还没有看到结尾(忽略)。 如果你再次按回车, gets将返回与填充7字节的house^Z (添加一个0字节表示字符串的结束)的缓冲区。 默认情况下,当从普通文件读取时,如果在文件中出现CTRL-Z字符,则忽略它之后的所有内容。 这是为了向后兼容CP / M,它只支持长度为128的倍数的文件,并使用CTRL-Z来标记文本文件真正应该结束的位置。
请注意,上述的Unix和windows行为都只是用户输入的正常默认处理。 Unix处理CTRL-D只能在规范模式下从终端设备读取,并且可以将“文件结束”字符改为别的。 在windows上, *** 作系统不会特别对待CTRL-Z,但是C运行时库是否取决于所读取的file流是处于文本模式还是二进制模式。 这就是为什么在可移植程序中,当打开二进制文件(例如fopen("foo.gif","rb") )时,应该总是在模式字符串中包含字符b 。
总结以上是内存溢出为你收集整理的Ctrl-D(Unix)和Ctrl-Z(Windows)的不同行为全部内容,希望文章能够帮你解决Ctrl-D(Unix)和Ctrl-Z(Windows)的不同行为所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)