在同一个文件中混合调用fgetc,ungetc()和fputc()时出错

wko9yo5t  于 2023-03-17  发布在  其他
关注(0)|答案(1)|浏览(89)

这段代码在同一个文件中混合调用 putc()ungetc()

#include <stdio.h>

int main(int argc, char *argv[])
{
    FILE *fp;
    int c;

    fp = fopen("filetest.txt", "r+");

    int fno = fileno(fp);

    /* get and print first position '1' */
    if((c = fgetc(fp)) == EOF){
        printf("fgetc(): error\n");
    }else{
        printf("%c\n", c);
    }

    /* get 2nd position '2' */
    if((c = fgetc(fp)) == EOF){
        printf("fgetc(): error\n");
    }

    /* put char 'X' in the 3rd position*/
    if((fputc('X', fp)) == EOF){
        printf("fputc(): error\n");
    }

    /* -- problematic code --- */
    /* Unget '2' */
    if (ungetc(c, fp) == EOF){
        printf("ungetc(): error\n");
    }

    /* get again and print '2' */
    if((c = fgetc(fp)) == EOF){
        printf("fgetc(): error\n");
    }else{
        printf("%c\n", c);
    }
    /* -- end of problematic code --- */

    /* get 4rd position '4' */
    if((c = fgetc(fp)) == EOF){
        printf("fgetc(): error\n");
    }else{
        printf("%c\n", c);
    }

    if (fclose(fp) != 0){
        printf("fclose(): error\n");
    }

}

作为“* filetest.txt”* 的内容:

12345

我以为输出结果会是:

1
2
4

但是我在 fgetc() 中得到了一个错误:

1
2
fgetc(): error
fclose(): error

如果删除了显示“problemble code”的部分,则输出正常:

1
4

为什么会失败?
由于stackoverflow不允许我发布它(代码太多,文本解释太少),下面是我尝试过的一些填充文本:

  • 阅读getc、fgetc、fputc和ungetc的手册页
  • 最初我使用的是putc,getc,所以我改为fputc和fputc来丢弃宏错误(我只是绝望了)

接下来是阅读getc,ungetc和putc的实现,但是我想知道在那之前是否有人能帮我解释一下这个...

m4pnthwp

m4pnthwp1#

下面是我所尝试的一些填充文本:

  • 阅读getc、fgetc、fputc和ungetc的手册页

我建议您也阅读man page for fopen,因为它指明了您做错了什么:
以更新模式打开文件时(“+”作为模式参数中的第二个或第三个字符),输入和输出都可以在相关流上执行。但是,应用程序应确保在没有对fflush的中间调用的情况下,输出后不直接跟随输入()或文件定位函数(fseek(),函数设置位置(),或倒带()),并且在没有对文件定位函数的介入调用的情况下,输入不直接跟随输出,除非输入操作遇到文件结束。
由于您的程序违反了此规则,因此它具有未定义的行为。
要解决此问题,使用明显的no-op语句就足够了

fseek( fp, 0, SEEK_CUR );

当从阅读改变到写时,反之亦然。

相关问题