【问题标题】:understanding fputc理解 fputc
【发布时间】:2012-04-01 08:42:10
【问题描述】:

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

这是我的脚本:

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.

【问题讨论】:

  • ./fputc > test.txt 将截断test.txt。你有两个文件(test.txt 和 text.txt)吗?你想用一个作为输入吗? (实在不清楚。)
  • 此代码无法检查fopen 调用的结果以确定它是否成功,但这不是当前问题的原因。它还应该检查fclose 的结果。

标签: c fopen getchar


【解决方案1】:

你的本质是:

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

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


您的控制台通常具有三个标准流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 中的任何内容重定向到 test.txt。

你说:

脚本没有到达 EOF

好吧,当它从stdin 读取时,它只会(并非没有例外)在两种情况下获得 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 ...

这将使你的代码更安全,给你提示它失败的地方等等。


一些链接:

【讨论】:

    【解决方案2】:

    getchar 从标准输入 (stdin) 返回下一个字符。 相当于 getc 以 stdin 为参数。

    因此,您的代码从标准输入而不是 FILE* 输入读取。

    在这里使用 fgetc。 fgetc 返回指定流的内部文件位置指示符当前指向的字符。然后内部文件位置指示器前进一个字符以指向下一个字符。

    所以,使用 fgetc 从文件中读取:

    while ((ch = fgetc(input)) != EOF)
    

    【讨论】:

      【解决方案3】:

      您的程序和外壳程序都在编写同一个文件。您应该从命令行中删除输出重定向> test.txt

      【讨论】:

        猜你喜欢
        • 2011-11-19
        • 2018-05-15
        • 2012-12-10
        • 1970-01-01
        • 2011-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-27
        相关资源
        最近更新 更多