Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用getchar()和putchar()复制文件_C_Eof_Getchar_Putchar - Fatal编程技术网

使用getchar()和putchar()复制文件

使用getchar()和putchar()复制文件,c,eof,getchar,putchar,C,Eof,Getchar,Putchar,我知道这之前已经讨论过了,但我想确保我正确理解,这个项目中发生了什么,以及为什么。在丹尼斯·里奇(Dennis Ritchie)的教科书《C编程语言》(The C Programming Language)的第20页上,我们看到了这个程序: #include <stdio.h> int main() { int c; c = getchar(); while(c != EOF){ putchar(c); c = getchar(); } return 0;

我知道这之前已经讨论过了,但我想确保我正确理解,这个项目中发生了什么,以及为什么。在丹尼斯·里奇(Dennis Ritchie)的教科书《C编程语言》(The C Programming Language)的第20页上,我们看到了这个程序:

#include <stdio.h>

int main()
{

int c;

c = getchar();

while(c != EOF){
    putchar(c);
    c = getchar();
}

return 0;

}
执行时,程序读取输入的每个字符,并在用户点击enter键后按相同顺序打印出来。除非用户手动退出控制台,否则此过程将无限期重复。事件顺序如下:

getchar函数读取输入的第一个字符,并将其值赋给c

因为c是整数类型,所以传递给c的getchar字符值将提升为其对应的ASCII整数值

既然c已经初始化为某个整数值,while循环可以测试该值是否等于文件末尾字符。由于EOF字符的宏值为-1,并且由于可以输入的字符中没有一个具有负十进制ASCII值,因此while循环的条件将始终为true

一旦程序验证c!=如果EOF为true,则调用putchar函数,该函数输出c中包含的字符值

再次调用getchar,以便读取下一个输入字符,并将其值传递回while循环的开头。如果用户在执行前只键入一个字符,那么程序将读取该值作为下一个字符,并打印新行,然后等待键入下一个输入


这些有一点是正确的吗?

是的,基本上你已经知道了。但它更简单:getchar和putchar已经分别返回和接受int类型。所以没有什么类型的促销活动。您只需接收字符并将其循环发送,直到看到EOF

您关于为什么这些应该是int而不是某种字符形式的直觉可能是正确的:int类型允许哨兵EOF值超出任何可能字符值的值范围

K&R stdio函数在这一点上非常古老,它们不知道Unicode等,一些基本的设计原理即使不模糊,也不相关。现在没有多少实用的代码会使用这些函数。那本书在很多方面都很好,但代码示例相当陈旧


另外,fwiw,你的问题标题指的是复制一个文件,你仍然可以这样做,但还有更多规范的方法,好吧,这在思想上是正确的,但在细节上不是,这就是魔鬼的所在

getchar函数从标准输入中读取第一个字符,并将其作为提升为int的无符号字符或特殊EOF值(如果未读取任何字符)返回

返回值被分配到c中,c的类型应该是int,如下所示

现在c已经被分配了一些整数值,while循环可以测试该值是否等于EOF宏的值

因为EOF宏有一个实现指定的负值,并且因为字符被转换为无符号字符并提升为int,所以它们都没有负值,至少在任何新手可能遇到的系统中都没有,while循环的条件将始终为true,直到文件结束条件发生或读取标准输入时出错

一旦程序验证c!=如果EOF为true,则调用putchar函数,该函数输出c中包含的字符值

再次调用getchar,以便读取下一个输入字符,并将其值传递回while循环的开头

如果连接到终端设备,则标准输入通常是行缓冲的,这意味着程序在用户完成该行并按下Enter键之前不会接收该行上的任何字符

我们所说的不是ASCII,而是执行字符集,它现在通常是UTF-8编码的Unicode字符的单个字节。EOF在二进制中也是负数,我们不需要考虑它的十进制值。char和unsigned char类型也是数字,字符常量是int类型-即,在执行字符集与ASCII兼容的系统上,写入“”与写入32是相同的事情,当然对于那些不记得ASCII代码的人来说更清楚

最后,C对初始化的含义要求非常严格。它是在声明变量时将初始值设置为变量

int c = getchar();
具有初始化

int c;
c = getchar();

未初始化c,然后分配了一个值。当编译器错误消息涉及初始化或赋值时,了解它们之间的区别可以更容易地理解它们。

没有EOF字符这样的东西。正如您所指出的,EOF是整数值-1,它不同于任何可能的字符值。getchar返回一个int,它是一个字符或EOF,用于终止程序。你怎么能
在控制台上使用EOF条件取决于操作系统。当然,如果您的输入是从一个文件重定向的,那么它将以实际的EOF条件自然终止。这就是为什么c必须声明为整数而不是字符的原因吗?所以表达式c!=可以评估EOF?用户点击enter后的思考与标准输入缓冲有关。它是行缓冲的,用户输入的内容由操作系统存储在缓冲区中,只有在用户输入enter或EOF.1后才会刷新到程序中。是的,2号,3号,4号。是的,5。请注意,在终端上,您可以键入一个字符,该字符最终可能被解释为表示EOF。在Unix上,这通常是Control-D;在Windows上,Control-Z。但是,该字符不是EOF;它可以出现在文件和Unix上,至少它只是另一个有效字符。在终端上键入时,终端驱动程序使从终端读取的程序可以使用任何等待的输入。如果没有数据等待,则表示有0个字节可用,这就是触发getchar等将其视为EOF的原因。当read返回0时,您在一个常规文件中达到EOF。是否有办法在读取所有用户输入后查看打印的EOF值,或者在输入完输入后输出-1的某种函数?@NicholasCousar:我不太明白-您指的是什么上下文?当getchar完成向您发送输入时,它确实应该吐出EOF-1。它理解输入的方式取决于它如何获得输入。如果您从命令行将其导入,shell将为您指示终止。如果你让它坐在那里接受键盘输入,你必须手动告诉它你已经完成输入,看看这个问题和答案,包括对它们的评论,这可能是有帮助的EOF不是一件事,它是一个事件。getchar通过返回-1通知您该事件。