高级编程(2)

今天主要讲一下这四个函数接口:fwrite、fread、fprintf、fsancf以及流的定位:ftell、rewind、fseek
函数接口

fwrite


fwrite:
    size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
    向流中写入number个对象,每个对象size字节大小,在ptr指向的空间中
参数:
    ptr:存放数据空间的首地址
    size:每个数据对象的大小
    number:数据对象的个数
    stream:文件流指针
返回值:
    成功返回写入对象的个数
    失败返回0
    读到文件末尾返回0 

例子:向file.txt文件中传入学生类型的结构体数据

#include<stdio.h>

typedef struct student{        //定义结构体
    char name[20];
    char sex;
    int age;
    int score;
}stu_x;

int main(void)        //主函数
{
    stu_x a = {"tom",'m',19,70};        //输入数据
    stu_x b = {"zero",'f',20,100};
    stu_x c[3] = {
        {"jack",'m',18,95},
        {"john",'f',19,80},
        {"lucky",'m',20,65},
    };

    FILE *fp = NULL;

    fp = fopen("file.txt","w");        //以写的方式打开文件

    if(NULL == fp)
    {
        perror("fail to fopen!");
        return -1;
    }

    fwrite(&a,sizeof(stu_x),1,fp);
    fwrite(&b,sizeof(stu_x),1,fp);
    fwrite(c,sizeof(stu_x),3,fp);

    fclose(fp);

    return 0;
}

数据已经写入文件中,但是cat只能显示ASCII码文件,不能显示二进制文件。

fread
fread:
    size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
    从流中读取nmemb个对象,每个对象size个字节,存放到ptr指向的空间中
参数:
    ptr:存放读取内容空间首地址
    size:读取对象的大小
    nmemb:读取对象的个数
    stream:文件流指针 
返回值:
    成功返回读到对象个数
    失败返回0
    读到文件末尾返回0 

我们可以将刚刚写入进去的数据重新读取出来:

#include<stdio.h>

typedef struct student        //fread读取数据的话,必须得要有数据的结构体
{
    char name[20];
    char sex;
    int age;
    int score;
}stu_t;

int ShowStuInfo(stu_t tmpstu)        //以这种方式输出
{
    printf("name  = %s\n",tmpstu.name);
    printf(" sex  = %c\n",tmpstu.sex);
    printf(" age  = %d\n",tmpstu.age);
    printf("score = %d\n",tmpstu.score);
}

int main(void)
{
    FILE *p = NULL;
    size_t ret;
    int i = 0;
    stu_t a;
    stu_t b[10];
    p = fopen("file.txt","r");

    if(NULL == p)
    {
        perror("fail to fopen");
        return -1;
    }
    
    fread(&a,sizeof(stu_t),1,p);    //取a的地址
    ShowStuInfo(a);
    ret = fread(b,sizeof(stu_t),10,p);    //取数组b的地址,ret可以看到文件中还有几组数据
    for(i = 0;i < ret;++i)
    {
        ShowStuInfo(b[i]);
    }

    fclose(p);

    return 0;
}


结果:

我们可以看到,再进行第二个fread时,我们写入的读取对象的个数是10,但是实际上只有4个,所以最后ret等于4。

fprintf
fprintf 
    int fprintf(FILE *stream, const char *format, ...);
功能:
    将格式化字符串输出到stream指向的流中

我的个人观点,认为这个实际上跟printf一样,只不过输入时需要加文件流指针,下面举一个例子:

#include<stdio.h>

int main(void)
{
    FILE *p = NULL;
    int Num1 = 100;
    int Num2 = 200;

    p = fopen("file.txt","w");

    if(NULL == p)
    {
        perror("fail to fopen");
        return -1;
    }

    fprintf(p,"hello world!\n num1 = %d , num2 = %d\n",Num1,Num2);    //将值输入到文件中

    fclose(p);

    return 0;
}


fscanf
fsancf 
    int fscanf(FILE *stream, const char *format, ...);
功能:
    从流中读取格式化的字符串

我们可以将文件中的数据进行提取出来。

第二部分就是流的定位


ftell
ftell
    long ftell(FILE *stream);
功能:
    获得流的偏移量

在进行第一次打开文件时,流的偏移量是0

rewind


rewind
    void rewind(FILE *stream);
功能:
    将流的偏移量重新设置到开头


fseek
fseek 
    int fseek(FILE *stream, long offset, int whence);
功能:
    设置流的偏移量
参数:
    stream:文件流指针
    offset:偏移量
    > 0 向后偏移
    < 0 向前偏移
whence:
    SEEK_SET    文件开头
    SEEK_CUR    文件当前位置
    SEEK_END    文件末尾

我们可以做一个简单的例子,方便于了解

#include<stdio.h>

int main(void)
{
    FILE *src = NULL;
    src = fopen("file.txt","w");

    if(NULL == src)
    {
        perror("fail to fopen");
        return -1;
    }

    fseek(src,10,SEEK_SET);        //在文件开头位置向右偏移10
    fputc('a',src);

    fseek(src,-5,SEEK_CUR);        //在文件当前位置向左偏移5
    fputc('c',src);

    fseek(src,0,SEEK_SET);        //回到文件开头位置
    fputc('b',src);

    fclose(src);
    
    return 0;
}


结果:

以上就是今天的所以内容,下面进行一个实例,从终端输入一个单词,获得单词的含义。

#include<stdio.h>
#include<string.h>

int main(void)
{
    FILE *src = NULL;
    src = fopen("dict.txt","r");    
    char word[256] = {0};
    char tmpbuff[4096];
    char *ptmp = NULL;
    char *pret = NULL;

    printf("please input one word:");
    gets(word);
    if(NULL == src)
    {
        perror("fail to fopen");
        return -1;
    }

    while(1)        //进行死循环
    {
        pret = fgets(tmpbuff,sizeof(tmpbuff),src);        //在源文件中,每一行结尾都有\n,所以我们可以使用fgets获得每一行的首地址,让pret进行记录
                                             //tmpbuff是存放字符串空间首地址,读取4096个字节,要保证足够大

        if(NULL == pret)    //判断是否读到文件末尾
        {
            break;
        }

        ptmp = tmpbuff;        

        while(*ptmp != ' ' && *ptmp != '\0')    //截取单词
        {
            ++ptmp;
        }

        *ptmp = '\0';        //将第一个空格的位置换成\0

        ptmp++;

        while(*ptmp == ' ')
        {
            ++ptmp;
        }

        if(strcmp(word,tmpbuff) == 0)    //进行字符串判断,看是否与输入的字符串相等
        {
            printf("word = %s\n",word);    //输出单词
            printf("ptmp = %s",ptmp);    //输出含义,因为已经截断了,所以ptmp当前的首地址是含义的地址
            return 0;
        }
    }

    fclose(src);

    printf("Word does not exist!\n");
    return 0;
}
结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值