c - 理解fputc

标签 c fopen getchar

我正在尝试对如何在 C 中使用 fputc 有一个基本的了解。我已经阅读了一些文档,并相信我的理解是正确的。但每次我尝试使用通过执行 ./fputc > test.txt 编写的脚本时,其中 text.txt 是一个包含一行文本的文本文件。

这是我的脚本:

int
main(int argc, char **argv){
    int ch;
    FILE *input;
    input = fopen("text.txt", "w+");
    while ((ch = getchar()) != EOF){
        fputc(ch, input);
    }
    fclose(input);

    return 0;
}

我在编译时没有遇到错误,并且由于某种原因,脚本没有到达文本文件末尾的 EOF。 getchar 到达文本文件末尾时不应该返回 EOF 吗? 文本 (text.txt) 文件虽然已创建,但似乎并未经过编辑。所以我的 while 循环中的某个地方出了问题。

我是 C 编程新手(如果你不知道的话),这个小脚本让我感到困惑。

任何帮助将不胜感激,或者任何包含更多详细信息的网站链接也将非常有用。

干杯,

S.

最佳答案

你本质上说的是:

  • 控制台:运行 my_program 并将其输出的任何内容写入 test.txt。

  • 程序:打开 text.txt 并将 stdin 的任何输入写入该文件。

<小时/>

您的控制台通常具有三个标准流 stdin , stdout and stderr 。这些流您可以 redirect 。如果您使用的是 Windows,还可以查看 redirection .

当你说./my_prog > test.txt时,你告诉你的控制台(不是 my_prog ),就是写任何东西 my_prog写入 stdout到文件test.txt

如果您在代码中说,即 printf("Hello"); ,那么 Hello 将被写入文件 test.txt .

如果您通过说 ./my_prog < test.txt 来扭转重定向相反,将会是; 将文件 test.txt 流式传输到 my_prog。反过来,如果 test.txt 中有任何文本,则会将 test.txt 复制到 text.txt。

现在在你的代码中你说:

int main(void) 
{
    int ch;
    FILE *input;

    /* Here you open a handle to the file text.txt for reading and writing */
    input = fopen("text.txt", "w+");

    while ((ch = getchar()) != EOF) { /* get next char from stdin */
        fputc(ch, input); /* write that char to the handle input */
    }
    fclose(input); /* close the handle */

    return 0;
}

那么,运行它的方式会发生什么:

在您的代码中:

  1. 打开text.txt
  2. 等待输入(输入到标准输入的数据) - 通常用户将文本输入到控制台,按下 Enter 时传递给程序。

在控制台中:

  1. 重定向来自 my_prog 的任何内容测试.txt。
<小时/>

你说:

the script does not reach EOF

好吧,正如它从stdin读取的那样它只会(并非无一异常(exception))在两种情况下得到 EOF。

  1. 如果您将文件重定向到您的程序。 IE。 ./my_prog < foo.txt (注意 < ,而不是 > )。
    - 那么会发生的是my_prog将从文件foo.txt读取数据当该文件结束时,您的程序将收到一个 EOF。并且,因此退出。

  2. 如果您手动输入 EOF 到 stdin .
    - 在 Linux 和 OSX 上Ctrl-D,在 Windows 上Ctrl-Z

<小时/>

现在,如果您通过在控制台中输入文本来测试这一点,请记住编写类似 fputc() 的操作。被缓冲。这意味着数据不会立即写入文件,而是仅当缓冲区中有给定量的数据时写入,fflush()被调用,流被关闭,您关闭缓冲等。

还有;如果你运行你的程序。输入文本,输入更多文本,然后按 Ctrl-C 中止程序,很有可能您的 text.txt 中没有任何数据。 .

原因是程序被杀死,从而 fclose()从未调用过,因此不会刷新到文件。

<小时/>

在你进一步努力编程时,养成不做任何假设的习惯是一个非常好的主意。 IE。不要假设fopen()没问题。

FILE *fh;
char *outfile = "foo.txt";

if ((fh = fopen(outfile, "w")) == NULL) {
    fprintf(stderr,
            "Unable to open file %s\n --",
            outfile);
    perror(" fopen() ");
    return 1;
}

大多数函数都有一种方法来检查操作是否成功。即:

if (fputc(ch, fh) != ch) { err ...

这将使您的代码更加安全,并提示您失败的地方等。

<小时/>

一些链接:

关于c - 理解fputc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9963059/

相关文章:

c - 打印字符串时出现意外结果

c - 为什么我的显存偏移量计算偏差了一个?

c - 有人可以告诉我我的错误吗?

c - C 中用户定义的数组程序出现问题

c - 将二维数组从 Julia 传递到 Fortran

c - 我怎样才能在某些情况下在 C 中使用 getch()?

创建带有 read( , , ) 错误的 getchar 函数

C getchar() 奇怪的行为

c - 更多地了解 fseek() 和 EOF IN C

matlab - 为什么 fopen 第一次失败,但第二次工作?