首页 > 系统相关 >io进程,标准io(函数接口)

io进程,标准io(函数接口)

时间:2024-08-31 10:21:46浏览次数:7  
标签:fp 文件 函数 int 接口 char io fopen buf

3.函数接口

3.1打开文件fopen

FILE *fopen(const char *path, const char *mode);

功能:打开文件

参数:

path:打开的文件路径

mode:打开的方式

r:只读,当文件不存在时报错,文件流定位到文件开头

r+:可读可写,当文件不存在时报错,文件流定位到文件开头

w:只写,文件不存在创建,存在则清空

w+:可读可写,文件不存在创建,存在则清空

a:追加(在末尾写),文件不存在创建,存在追加,文件流定位到文件末尾

a+:读和追加,文件不存在创建,存在追加,读文件流定位到文件开头,写文件流定位到文件末尾

注:当a+的方式打开文件时,写只能在末尾进行追加,定位操作是无法改变写的位置,但是可以改变读的位置

返回值:

成功:文件流

失败:NULL,并且会设置错误码

补充:

perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 设备 (stderr) 。参数 s 所指的字符串会先打印出, 后面再加上错误原因字符串。此错误原因依照全局变量errno 的值来决定要输出的字符串。 在库函数中有个errno变量,每个errno值对应着以字符串表示的错误类型。当你调用"某些"函数出错时,该函数已经重新设置了errno的值。perror函数只是将你设置的一些信息和现在的errno所对应的错误一起输出。

3.2关闭文件

fclose()

功能:关闭文件

参数:文件流

#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;
    //1.打开文件
    //fp = fopen("test.txt", "r"); //如果不存在会错误,因为只读r模式
    fp = fopen("test.txt", "w");
    if (NULL == fp)
    {
        perror("fopen err");
        // while(1);  //标准错误不缓存,错误信息会打印
        return -1;
    }
    printf("fopen success\n");

    //2.关闭文件
    fclose(fp);
    return 0;
}

3.3文件读写操作

3.3.1每次读一个字符:fgetc(),fputc()

每次读一个字符fgetc()

fgetc()

功能:从文件中读取一个字符,并且将当前文件指针位置向后移动一个字符

参数:文件流

返回值:

成功:读到的字符

失败或者读到文件末尾:EOF(-1)

每次写入一个字符fputc()

fputc()

功能:向文件写入一个字符,成功写入后文件指针自动向后移动一个字节位置

参数:要写的字符      文件流

返回值

成功,写入的字符的ascii

失败EOF(-1)

(1)针对文件读写

#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;
    //1.打开文件
    fp = fopen("test.txt", "r+");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }
    printf("fopen success\n");

    char ch = fgetc(fp);
    printf("%d %c\n", ch, ch); //104 h

    ch = fgetc(fp);
    printf("%d %c\n", ch, ch); //101 e

    fputc('a', fp); //向文件中写个a
    fputc('b', fp); //向文件中写个b

    ch = fgetc(fp);
    printf("%d %c\n", ch, ch); //-1 EOF 因为以及到末尾了

    //2.关闭文件
    fclose(fp);
    return 0;
}

(2)针对终端的读写

#include <stdio.h>

int main(int argc, char const *argv[])
{
    char ch;
    ch = fgetc(stdin); //相当于getchar()
    printf("%d %c\n", ch, ch);

    fputc(ch, stdout); //相当于putchar()
    fputc(10, stdout);
    fputc('b', stdout);
    return 0;
}

补充feof和ferror

int feof(FILE * stream);

功能:判断文件有没有到结尾,也就是当前所在位置后面还有没有字符。

返回:如果到达文件末尾,返回非零值。如果后面还有字符则返回0。

例子:

int ferror(FILE * stream);

功能:检测文件有没有出错

返回:文件出错,返回非零值。如果没有出错,返回0。

练习;cat文件名

#include <stdio.h>
/* cat 文件名:查看文件内容,显示到终端。
   步骤:
        1.打开文件 fopen
        2.循环用fgetc获取文件内容
        3.当读到文件末尾标志EOF时结束
        4.将读取文件内容用fputc打印到终端
        5.关闭文件
*/
int main(int argc, char const *argv[])
{
    if (argc != 2)
    {
        printf("err: %s <filename>\n", argv[0]); //提示一下正确的格式
        return -1;
    }

    //1.打开文件
    FILE *fp = fopen(argv[1], "r");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }

    //2.循环用fgetc读文件,只要读到就fputc打印到终端
    char ch;
    while ((ch = fgetc(fp)) != EOF)
        fputc(ch, stdout);   //将读到字符打印到终端
  
    //3. 关闭文件
    fclose(fp);

    return 0;
}

3.3.2每次一个字符串的读写fgets()和fputs()

fgets()

功能:从文件中每一次读取一个字符串

参数:

存放字符串的地址

期望一次读取的字符个数

文件流

返回值

成功,存发给字符串的地址

失败或者读到文件末尾:NULL

fputs()

功能:向文件中写入字符串

参数:

要写的内容

文件流

返回值:

成功,非负整数

失败EOF

(1)针对终端的读写

#include <stdio.h>

int main(int argc, char const *argv[])
{
    char buf[32] = "";
    //输入操作
    fgets(buf, 32, stdin); //输入hello\n,  此时buf中存入内容: hello\n\0
    printf("buf: %s\n", buf);

    fgets(buf, 32, stdin); //输入66\n,  此时buf中内容: 66\n\0o\n\0
    printf("buf: %s\n", buf);

    //输出操作
    fputs("world", stdout);
    fputs(buf, stdout);

    return 0;
}

(2)针对文件的读写

#include <stdio.h>
int main(int argc, char const *argv[])
{
    FILE *fp;
    char buf[32] = "";

    fp = fopen("test.txt", "r+");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }
    printf("fopen success\n");
    //读写操作
    fgets(buf, 32, fp); //buf:hello\n\0
    fputs(buf, stdout);

    fgets(buf, 32, fp); //buf:world\n\0
    fputs(buf, stdout);

    fgets(buf, 32, fp); //buf: 66\0ld\n\0
    fputs(buf, stdout);

    fclose(fp);
    return 0;
}

通过fgets实现wc -l文件名实现计算文件行数的命令功能

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    FILE *fp;
    char buf[32] = "";

    if (argc != 2)
    {
        printf("err: %s <filenme>\n",argv[0]);
        return -1;
    }

    fp = fopen(argv[1], "r");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }

    //循环fgets读文件, 只要读到就判断是否有\n, 如果有就累加行数
    int len = 0;
    while (fgets(buf, 32, fp) != NULL)
    {
        if (buf[strlen(buf) - 1] == '\n')
            len++;
    }
    printf("%d %s\n", len, argv[1]);  //wc -l会少一行,因为最后一行没有换行

    fclose(fp);
    return 0;
}

3.3.3二进制读写fread(),fwrite()

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从文件流读取多个元素(将二进制数据从文件读出)
参数:  ptr :是一个指针,是存放数据的存储空间的起始地址,用来存放读取元素
       size :元素大小  sizeof(元素数据类型)
       nmemb :读取元素的个数
       stream :要读取的文件流
返回值:成功:读取的元素的个数
       读到文件尾或失败: 0

size_t fwrite(const void *ptr, size_t size, size_t nmemb,
              FILE *stream);
功能:将二进制数据写入文件
参数: ptr :是一个指针,保存要输出数据的空间的地址。
     size :要写入的字节数 sizeof(数据类型)
     nmemb : 要进行写入元素的个数
      strem: 目标文件流指针
返回值:成功:写的元素个数
              失败 :-1

(1)针对终端的读写

//针对终端
    char buf[32] = "";
  
    fread(buf, sizeof(char), 10, stdin);
    printf("printf:%s\n", buf);
    fwrite(buf, 1, 10, stdout);

针对文件的读写

#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;
    float arr[3] = {1.23, 2.34, 4.56};
    float data[3] = {0};

    fp = fopen(argv[1], "r+");
    if (fp == NULL)
    {
        perror("fopen err");
        return -1;
    }
    fwrite(arr, sizeof(float), 3, fp);
    //将位置指针定位到文件开头,不然上一步是写操作所以接着读的话会从末尾开始读从而什么都读不到
    rewind(fp); //定位到文件开头

    fread(data, 4, 3, fp);
    printf("%f %f %f\n", data[0], data[1], data[2]);

    return 0;
}

3.4其他操作

3.4.1重定向流到文件freopen

ILE * freopen(const char *pathname,  const char *mode,  FILE* fp);
功能:将指定的文件流重定向到打开的文件中
参数:path:文件路径
     mode:打开文件的方式(同fopen)
     fp:文件流指针
返回值:成功:返回打开的文件流指针
      失败:NULL
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("hello\n");
    //将标准输出流重定向到打开的test.txt文件中
    freopen("test.txt", "w+", stdout);
    printf("world\n");
    //将标准输出重定向到终端文件
    freopen("/dev/tty", "r+", stdout);
    printf("6666666666666666\n");

    return 0;
}

3.4.2文件定位操作

void rewind(FILE *stream);
功能:将文件位置指针定位到起始位置

int fseek(FILE *stream, long offset, int whence);
功能:文件的定位操作
参数:stream:文件流
     offset:偏移量:正数表示向后文件尾部偏移,负数表示向文件开头偏移
     whence:相对位置:
           SEEK_SET:相对于文件开头
           SEEK_CUR:相对于文件当前位置
           SEEK_END:相对于文件末尾
返回值:成功:0
       失败:-1   
注:当打开文件的方式为a或a+时,fseek不起作用      

补充:其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.
简言之:
fseek(fp,100,0);把fp指针移动到离文件开头100字节处.
fseek(fp,100,1);把fp指针移动到离文件当前位置100字节处;
fseek(fp,-100,2);把fp指针退回到离文件结尾100字节处。
   
long ftell(FILE *stream);
功能:获取当前的文件位置
参数:要检测的文件流
返回值:成功:当前的文件位置,出错:-1
#include <stdio.h>
int main(int argc, char const *argv[])
{
    FILE *fp = fopen("test.txt", "w+");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }
    printf("fopen success\n");

    //相当于开头位置,往后10个
    fseek(fp, 10, 0);
    fputc('a', fp);

    //相对于当前位置,往后5个
    fseek(fp, 5, 1);
    fputs("hello", fp);

    //相对于最后位置,往前1个
    fseek(fp, -1, 2);
    fputc('b', fp);

    //计算文件位置
    long l = ftell(fp);
    printf("%ld\n", l);

    return 0;
}

总结

为什么要用标准io

1.因为读写文件通常是大量的数据,库函数可以大量减少系统调用的次数

2.为了保持可移植性

关于缓存区

 库函数的缓冲区对于库函数,如果标准输出连到终端设备(直接输出到屏幕),则它是行缓冲的(遇到回车换行符或者是缓冲区满了才输出);否则(输出到文件)是全缓冲的(缓冲区填满或者是程序运行结束了才输出)。程序运行结束时,会刷新所有的缓冲区。

标签:fp,文件,函数,int,接口,char,io,fopen,buf
From: https://blog.csdn.net/weixin_64032452/article/details/141743883

相关文章

  • IO练习:用信号实现司机和售票员问题
    【1】问题描述 1)售票员捕捉SIGINT(代表开车)信号,向司机发送SIGUSR1信号,司机打印(let'sgogogo)2)售票员捕捉SIGQUIT(代表停车)信号,向司机发送SIGUSR2信号,司机打印(stopthebus)3)司机捕捉SIGTSTP(代表到达终点站)信号,向售票员发送SIGUSR1信号,售票员打印(pleasegetoffthebus)4)司......
  • IO进程练习:请在linux 利用c语言编程实现两个线程按照顺序依次输出”ABABABAB......“
    例如:a线程输出”A”之后b线程输出”B”,然后a线程输出“A”,再b线程输出”B”,之后往复循环。【1】使用信号量实现代码展示:#include<stdio.h>#include<pthread.h>#include<string.h>#include<semaphore.h>#include<unistd.h>//定义两个全局信号量,实现同步机制se......
  • wpf-Application的生命周期
    在WPF中,App类继承自Application类,Application类当中有四个虚方法,分别为OnStartup、OnActivated、OnDeactivated、OnExit。在App类文件中重载这四个方法,同时分别输出以下内容。OnStartup方法:应用程序启动阶段被调用,此方法允许用户在主窗口界面显示之前执行自定义操作,例如身份验......
  • wbemtest.exe 是 Windows 操作系统中的一个实用程序,用于测试和调试 Windows Managemen
    wbemtest.exe起源于Windows操作系统的WMI(WindowsManagementInstrumentation)框架。它首次引入于Windows2000,作为一个图形化工具,帮助用户和开发者测试和调试WMI查询、操作和配置。其目的是简化与WMI服务的交互,提供一个直观的界面用于管理和排查系统管理数据。wbemte......
  • 载波监听多址接入碰撞检测 CSMA/CD(carrier sense multiple access collision detecti
    载波监听多址接入/碰撞检测CSMA/CD(carriersensemultipleaccess/collisiondetection)概念解析在总线局域网使用的协议多址接入MA:多个站连接在同一条线上,竞争使用总线。载波监听CS:每一个站在发送帧之前都要检测一下总线上是否有其他站点在发送帧(”先听后说“)......
  • Elsevier 期刊 Expert SystemsWith Applications 投稿经验
    准备材料1.AuthorAgreement:带全部作者的电子签名,证明全部作者对该论文的知情2.CoverLetter:介绍该文章的工作内容,不是简单的把摘要复制过来3.ORCIDInformation:写上全部作者姓名以及对应的orcid4.Highlights:3-5点即可,这里需要注意字数5.CreditAuthorStatement:说明每一......
  • DaVinci Resolve Studio 19.0 正式版 (macOS, Windows) - 剪辑、调色、特效和音频后期
    DaVinciResolveStudio19.0正式版(macOS,Windows)-剪辑、调色、特效和音频后期制作BlackmagicDesignDaVinciResolveStudio请访问原文链接:https://sysin.org/blog/davinci-resolve/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgDaVinciResolve19免费!......
  • 致远互联-分析云 getolapconnectionlist 逻辑漏洞
       声明:本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动,将与本文档的作者或发布者无关。一、漏洞描述致远分析云是由北京致远互联精心打造的一站式数据分析平台,旨在助力企业实现数字化转型升级。二,fofa语法body="js/lib/ba.co......
  • django.core.exceptions.ImproperlyConfigured: 'django.contrib.gis.db.backends.mys
     没解决此问题(venv)[root@VM-8-12-centosMYPROJECT-django20240830]#python3manage.py runserver0.0.0.0:8080Exceptioninthreaddjango-main-thread:Traceback(mostrecentcalllast): File"/root/MYPROJECT/backend/venv/lib/python3.8/site-packages/django/d......
  • [Raspberry Pi]如何利用docker執行motioneye,並利用Line Notify取得即時通知和照片?
    [Motioneye]Howtosetupmotiondetectionandsendmessage/imageforLineNotify無意間,翻了一本關於樹莓派的書籍,除了樹莓派的簡介和應用外,也包含初階和高階的Linux運作邏輯,書籍結構相當完整,也因此需要花時間細細體會其內容。其在樹莓派的應用內容,提及一款開源影像監視......