fgetc()、fputc()函数的使用实例

本文介绍了C语言中fgetc和fputc函数的使用,通过实例展示了如何读写文件,并讨论了如何判断文件尾和处理文件读取错误,包括feof和ferror函数的应用。
摘要由CSDN通过智能技术生成

       在下面的程序中, 我们将通过键盘键入的字符依次写入demo.txt中. 

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp;/* 定义文件指针fp */
    char ch;
    if((fp = fopen("C:\\Users\\surface\\Desktop\\demo.txt", "w")) == NULL)/* 以只写的方式打开文件 */
    {
        /* 打开文件时发生错误 */
        printf("Failure to open demo.txt!\n");
        exit(0);
    }
    ch = getchar();
    while(ch != '\n')
    {
        fputc(ch, fp);/* 将刚刚输入的字符写入fp指向的文件中 */
        ch  = getchar();
    }
    if(fclose(fp) == 0)
    {
        /* 文件关闭成功, fclose()返回0 */
        printf("Success for writing the string to file demo.txt.\n");
    }
    else
    {
        /* 文件关闭失败, fclose()返回EOF(-1) */
        exit(0);
    }
    return 0;
}

[运行结果]

       在程序运行前, 指定目录(桌面)下无demo.txt文件, 接下来运行上述程序.

       此时切回桌面, 发现demo.txt文件已自动创建.

       接着我们打开文件, 查看文件中的内容.

        可以发现, 文件中的内容就是我们刚才从键盘输入的内容.

        随后我们再次运行上述程序.

       在程序运行后, 再次查看demo.txt中的内容.

       可以发现, 之前文件中的内容已被清除, 取而代之的是我们刚刚通过键盘键入的信息: 这也是用fopen函数以w模式打开文件的特点. 

       如果我们希望将demo.txt文件中的内容通过屏幕显示出来, 则需要借助于fgetc函数实现.

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp;/* 定义文件指针fp */
    char ch;
    if((fp = fopen("C:\\Users\\surface\\Desktop\\demo1.txt", "r")) == NULL)/* 以只读的方式打开文件 */
    {
        /* 打开文件时发生错误 */
        printf("Failure to open demo.txt!\n");
        exit(0);
    }
    ch = fgetc(fp);
    while(ch != EOF)/* 只要从文件中读取的字符不是文件结束符EOF, 循环就继续下去 */
    {
        putchar(ch);/* 将刚刚从文件中读取的字符输出到屏幕上 */
        ch  = fgetc(fp);/* 从文件中读取下一字符, 并保存在ch变量中 */
    }
    if(fclose(fp) == 0)
    {
        /* 文件关闭成功, fclose()返回0 */
        printf("\nSuccess for reading the string from file demo.txt.\n");
    }
    else
    {
        /* 文件关闭失败, fclose()返回EOF(-1) */
        exit(0);
    }
    return 0;
}

       运行上面的程序.

       可以看出, 文件demo.txt中的内容成功地出现在屏幕上. 

       如果我们将demo.txt改为demo1.txt(此文件不存在), 程序还会自动生成demo1.txt吗?

       此时, 程序打开demo1.txt文件失败, 这也说明用fopen函数以"r"模式打开文件时, 若指定文件不存在, 程序不会自动创建该文件. 

       除了通过判断读出的字符是否为文件结束符EOF外, 另外还可以调用C语言为我们提供的一个标准库函数来判断是否已经定位到文件尾: 这个库函数就是feof, 该函数的功能就是用于检测是否已经到达文件尾. 当检测到文件尾时, 返回非零值; 否则返回0. 

       下面对上述程序略作修改, 即将while循环的判断条件改为 feof(fp) == 0, 以此代替上述程序中的 ch != EOF.

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp;/* 定义文件指针fp */
    char ch;
    if((fp = fopen("C:\\Users\\surface\\Desktop\\demo.txt", "r")) == NULL)/* 以只读的方式打开文件 */
    {
        /* 打开文件时发生错误 */
        printf("Failure to open demo.txt!\n");
        exit(0);
    }
    ch = fgetc(fp);
    while(feof(fp) == 0)/* 只要从文件中读取的字符不是文件结束符EOF, 循环就继续下去 */
    {
        putchar(ch);/* 将刚刚从文件中读取的字符输出到屏幕上 */
        ch  = fgetc(fp);/* 从文件中读取下一字符, 并保存在ch变量中 */
    }
    if(fclose(fp) == 0)
    {
        /* 文件关闭成功, fclose()返回0 */
        printf("\nSuccess for reading the string from file demo.txt.\n");
    }
    else
    {
        /* 文件关闭失败, fclose()返回EOF(-1) */
        exit(0);
    }
    return 0;
}

       接下来我们如下图示修改while循环体内的语句, 运行程序, 查看运行结果是否正确.

       从程序的运行结果来看, 似乎一切都很正常.

       接着, 我们将while循环体内的putchar函数改为printf函数, 并附加输出每个字符在文件中的位置, 看看运行结果会有什么不同.

       可以发现, 输出结果较之前的程序多了一个输出, 那么这种现象背后的原因是什么呢?

       在上面的程序中, 最后一次循环用fgetc函数从文件中读出的字符实际上就是文件结束符EOF(ASCII码值为-1), 这样一来程序的输出多出一行也就并不奇怪了. 这说明feof函数只有当读到文件结束符时, 才能判断出到达文件尾: feof函数总是在读完文件所有内容后, 再执行一次读文件操作, 将文件结束符EOF读走, 才能返回非0值

       针对上面将文件结束符也输出的问题, 可以像下面这样解决.

[解决方案1]

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp;/* 定义文件指针fp */
    char ch;
    long pos;
    if((fp = fopen("C:\\Users\\surface\\Desktop\\demo.txt", "r")) == NULL)/* 以只读的方式打开文件 */
    {
        /* 打开文件时发生错误 */
        printf("Failure to open demo.txt!\n");
        exit(0);
    }
    pos = ftell(fp);
    ch = fgetc(fp);
    while(feof(fp) == 0)/* 只要从文件中读取的字符不是文件结束符EOF, 循环就继续下去 */
    {
        printf("%c, %ld\n", ch, pos);
        pos = ftell(fp);
        ch  = fgetc(fp);/* 从文件中读取下一字符, 并保存在ch变量中 */
    }

    if(fclose(fp) == 0)
    {
        /* 文件关闭成功, fclose()返回0 */
        printf("\nSuccess for reading the string from file demo.txt.\n");
    }
    else
    {
        /* 文件关闭失败, fclose()返回EOF(-1) */
        exit(0);
    }
    return 0;
}


[解决方案2]

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp;/* 定义文件指针fp */
    char ch;
    long pos;
    if((fp = fopen("C:\\Users\\surface\\Desktop\\demo.txt", "r")) == NULL)/* 以只读的方式打开文件 */
    {
        /* 打开文件时发生错误 */
        printf("Failure to open demo.txt!\n");
        exit(0);
    }
    pos = ftell(fp);
    ch = fgetc(fp);
    while(ch != EOF)/* 只要从文件中读取的字符不是文件结束符EOF, 循环就继续下去 */
    {
        printf("%c, %ld\n", ch, pos);
        pos = ftell(fp);
        ch  = fgetc(fp);/* 从文件中读取下一字符, 并保存在ch变量中 */
    }

    if(fclose(fp) == 0)
    {
        /* 文件关闭成功, fclose()返回0 */
        printf("\nSuccess for reading the string from file demo.txt.\n");
    }
    else
    {
        /* 文件关闭失败, fclose()返回EOF(-1) */
        exit(0);
    }
    return 0;
}

        可对解决方案2中蓝色区域做出精简, 精简后的程序如下示.

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp;/* 定义文件指针fp */
    char ch;
    long pos;
    if((fp = fopen("C:\\Users\\surface\\Desktop\\demo.txt", "r")) == NULL)/* 以只读的方式打开文件 */
    {
        /* 打开文件时发生错误 */
        printf("Failure to open demo.txt!\n");
        exit(0);
    }
    pos = ftell(fp);
    while((ch = fgetc(fp)) != EOF)/* 只要从文件中读取的字符不是文件结束符EOF, 循环就继续下去 */
    {
        printf("%c, %ld\n", ch, pos);
        pos = ftell(fp);
    }

    if(fclose(fp) == 0)
    {
        /* 文件关闭成功, fclose()返回0 */
        printf("\nSuccess for reading the string from file demo.txt.\n");
    }
    else
    {
        /* 文件关闭失败, fclose()返回EOF(-1) */
        exit(0);
    }
    return 0;
}

       接下来我们再来探讨一个问题, 当读到文件尾或发生读取错误时, fgetc函数均返回EOF, 所以当fgetc函数返回EOF时, 我们并不能确定导致这一现象发生的原因. 由此可见, 用EOF来判断是否到达文件尾的方法并不是一种很严谨的方法, 即我们不能用判断fgetc函数是否返回EOF来完全代替feof函数的作用(最好还是用feof函数来判断是否已经到达文件尾). 

       检测是否发生文件读取错误的函数是ferror(), 出错时ferror函数返回非0值, 否则返回0.

     最后, 给出具备文件读取检错功能的程序实现. 

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp;/* 定义文件指针fp */
    char ch;
    long pos;
    if((fp = fopen("C:\\Users\\surface\\Desktop\\demo.txt", "r")) == NULL)/* 以只读的方式打开文件 */
    {
        /* 打开文件时发生错误 */
        printf("Failure to open demo.txt!\n");
        exit(0);
    }
    pos = ftell(fp);
    while((ch = fgetc(fp)) != EOF)/* 只要从文件中读取的字符不是文件结束符EOF, 循环就继续下去 */
    {
        if(ferror(fp) != 0)
        {
            /* 发生文件读取错误 */
            printf("Error on file.\n");
            exit(0);
        }
        printf("%c, %ld\n", ch, pos);
        pos = ftell(fp);
    }

    if(fclose(fp) == 0)
    {
        /* 文件关闭成功, fclose()返回0 */
        printf("\nSuccess for reading the string from file demo.txt.\n");
    }
    else
    {
        /* 文件关闭失败, fclose()返回EOF(-1) */
        exit(0);
    }
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好梦成真Kevin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值