首页 > 系统相关 >IO进程(标准IO)

IO进程(标准IO)

时间:2024-08-26 19:27:11浏览次数:9  
标签:fp 文件 int char 标准 tm IO 进程 指针

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);

    1. 针对文件读写
#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

FILE * 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;
}

练习题:

  1. 相对一个文本文件的尾部追加写入,应当在fopen何中使用的文件操作方式指示符号为 ()       A.r B.wb C. a D.w+
  2. fseek(1, 2, 3); 这个函数是什么作用,三个参数分别是什么意思?
  3. 函数调用语句:fseek (fp,-10L,2);的含义是

A 将文件位置指针从文件未尾处向文件头的方向移动10个字节

B 将文件位置指针从当前位置向文件头的方向移动10个字节

C 将文件位置指针从当前位置向文件未尾方向移动10个字节

总结:

为什么用标准IO?

  1. 因为读写文件通常是大量的数据(相对于底层驱动的系统调用所实现的数据操作单位),这时,使用库函数可以大大减少系统调用的次数。
  2. 为了保证可移植性

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

最后给大家留一个小小的练习题。我把思路和代码都附上了,大家做完可以参考一下。

编程读写一个文件test.txt,每隔1秒向文件中写入一行录入时间的数据,类似这样:

1,  2007-7-30 15:16:42  

2,  2007-7-30 15:16:43

该程序应该无限循环,直到按Ctrl-C中断程序。

再次启动程序写文件时可以追加到原文件之后,并且序号能够接续上次的序号,比如:

1,  2007-7-30 15:16:42

2,  2007-7-30 15:16:43

3,  2007-7-30 15:19:02

4,  2007-7-30 15:19:03

5,  2007-7-30 15:19:04

思路:

  1. 打开文件fopen,循环往文件写内容
  2. 每隔1s写入一行,sleep(1);
  3. 计算文件行数,wc -l
  4. 计算当前时间,转换成年月日、时分秒,time,localtime

man 2 time

time_t time(time_t *t);

如果t是空指针,直接返回当前时间。如果t不是空指针,返回当前时间的同时,将返回值赋予t指向的内存空间。

man 3 localtime

struct tm *localtime(const time_t *timep);

返回值是结构体指针,所指结构体封装着年月日时分秒

  1. 字符串拼接函数:strcpy/strcat(dest, src)、sprintf、fprintf

fprintf:

格式化输出到流(stream)文件中,返回值是输出的字符数,发生错误时返回一个负值.

int fprintf( FILE *stream, const char *format, ... );

sprintf:

格式化输出发送到buffer(缓冲区)中.返回值是写入的字符数量.

int sprintf( char *buffer, const char *format, ... );

代码实现:

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

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], "a+");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }

    //2. 计算行数
    char buf[32] = "";
    int len = 0;
    while (fgets(buf, 32, fp) != NULL)
    {
        if (buf[strlen(buf) - 1] == '\n')
            len++;
    }

    //3. 循环把时间戳写入文件,1s一行
    time_t t;
    struct tm *tm;
    while (1)
    {
        time(&t);
        tm = localtime(&t);
        fprintf(fp, "%d, %d-%d-%d %d:%d:%d\n", ++len, tm->tm_year + 1900,
                tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
        sleep(1);
        fflush(NULL);
    }

    return 0;
}

明天为大家更新文件IO的相关内容。

标签:fp,文件,int,char,标准,tm,IO,进程,指针
From: https://blog.csdn.net/2301_77143270/article/details/141571121

相关文章

  • Request processing failed:MyBatisSystemException 黑马web开发课程P152中可能出现的
    该异常的最后一句,通过翻译,大概是:   [dispatcherServlet]:servlet.service()forservlet[dispatcherServlet]在路径[]的上下文中抛出异常[请求处理失败:MyBatisSystemException]    经过对代码的检查,发现controller,sevice,dao层业务逻辑都没有问题dao层的map......
  • SwapPrompt(论文解读): Test-Time Prompt Adaptation for Vision-Language Models
    2023(NeuralIPS)摘要测试自适应(TTA)是无监督域自适应(UDA)中一种特殊且实用的设置,它允许源域中的预训练模型去适应另一个目标域中的未标记测试数据。为了避免计算密集型的骨干网络微调过程,因此利用预训练视觉语言模型(例CLIP、CoOp)zero-shot的泛化潜力,仅对未见测试域的运行时......
  • (论文解读)Domain Adaptation via Prompt Learning
    摘要无监督域适应(UDA)旨在将从带有标签的源域数据中学习到的模型适应到未标注的目标域数据集。现有的UDA方法通过对齐源域和目标域特征空间来学习领域不变特征。这种对齐是通过约束实现的,例如统计差异最小化或对抗学习。然而,这些约束会导致语义特征结构的扭曲和类别判别性......
  • 论文解读Multi-Prompt Alignment for Multi-Source Unsupervised Domain Adaptation
    Multi-PromptAlignmentforMulti-SourceUnsupervisedDomainAdaptationNeurlIPS2023摘要大多数现有的无监督域适应(UDA)方法依赖于共享网络来提取领域不变特征。无论如何,当面对多个源域时,优化这样的网络涉及更新整个网络的参数,这样既昂贵又有挑战性,特别是与最小最大......
  • Robot_localization,将NED imu转为相对、绝对航向的 “ENU“ 数据
    Robot_localization,将NEDimu转为相对、绝对航向的"ENU"数据文章约定:谈及NED、ENU、NWU坐标系都是指的xyz对应顺序ROS中,xyz轴对应红、绿、蓝如有错误,请包容,以及麻烦在评论区勘误书山有路勤为径,学海无涯苦作舟1.问题来源使用robot_localization进行:imu融合gps......
  • x86 ubuntu20.04 ros:noetic-perception-focal 镜像测试
    https://hub.docker.com/_/ros/tags?page=&page_size=&ordering=&name=noetic1.启动容器:dockerpullros:noetic-perception-focaldockerrun-it--envDISPLAY=$DISPLAY--volume/tmp/.X11-unix:/tmp/.X11-unix--privileged--gpusall--volume/home/h/doc......
  • Java 入门指南:初识 Java IO
    JavaIOJavaIO(Input/Output)是Java编程语言中用于处理输入和输出的标准库,它提供了一组类和接口,用于在程序和外部世界(如文件、网络连接、内存等)之间进行数据传输。IO,即in和out,也就是输入和输出,即应用程序和外部设备之间的数据传递,常见的外部设备包括文件、管道、网络......
  • el-input-number设置精度precision=2,输入2自动变成了2.00怎么办?
    问题背景项目:vue2+elementui老板说:有一个需求,这个输入框最多输入4位数,如果有小数的话,最多输入4位小数,能做吗?我说:“能!”然后我就兴冲冲地做了起来。我一想:“这个直接用el-input-number写不就好了吗”然后我设置了:(最大值9999,精度设置为4,即保留4位小数)<el-input-num......
  • C#进阶-快速了解IOC控制反转及相关框架的使用
    目录一、了解IOC1、概念2、生命周期二、IOC服务示例1、定义服务接口 2、实现服务三、扩展-CommunityToolkit.Mvvm工具包Messenger信使方式一(收发消息)方式二(收发消息)方式三(请求消息)一、了解IOCIOC,即控制反转(InversionofControl),它通过将对象的创建和管理责任从......
  • 已解决org.xml.sax.SAXNotRecognizedException异常的正确解决方法,亲测有效!!!
    要解决org.xml.sax.SAXNotRecognizedException异常,通常涉及以下步骤。这种异常通常是由于SAX解析器不识别或不支持某些特性或属性导致的。以下是具体的解决方案:1.确认属性或特性的正确性确保你设置的属性或特性名称是正确的,并且该解析器确实支持。例如:SAXParserFact......