linux 底层标准IO(二)

本文探讨了标准IO与系统IO的区别,重点介绍了标准IO的高效性及其在文件操作中的应用。通过多个实验,包括文件读写、结构体操作、文件复制及定时文件更新等,深入理解标准IO函数如fputs(), fgets(), fprintf()等的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面说标准IO和IO系统接口是稍微有点区别,就是标准IO带有用户缓存。这也是标准IO效率高的原因。

实验内容

  1. 用标准IO,编写程序2_1.c,以读写方式打开文件file_3,如果该文件不存在,则创建。如果该文件已经存在,则长度截短为0。
  2. 编写程序2_2.c,实现将文件1.txt中的ip地址“192.168.1.100”解析出来,并打印到屏幕上。尝试用行读写函数,fputs()和fgets()。                                                                                                                                                                                        注意:对于fgets()函数,必须指定缓存的长度n。此函数一直读到换行符为止,但是不超过n-1个字符,读入的字符被送入缓存。该缓存以空字符\0结尾。
  3. 用标准IO编写程序2_3.c,实现读或写一个结构体,将一个结构体写至一个文件test_file_5上,并打开文件查看里面的内容(是否是乱码),并将文件中的内容用fread()函数读出来,并打印在屏幕上查看是否正查显示.
  4. 用标准IO库函数自己编写一个简单的copy程序fmycopy.c,完成文件的复制。
  5. 编程读写一个文件time.txt,每隔1秒向文件中写入一行数据,该程序应该无限循环,直到强制中断该进程为止(比如按Ctrl-C中断程序)。接着再启动程序,将系统时间追加到原文件之后,并且序号能够接续上次的序号

 

1. 

fprint()与printf()函数相比多出来了第一个参数FILE*stream,其意义是将打印的内容输出到文件流指针stream所指向的流。所谓流,通常是指程序输入或输出的一个连续的字节序列,设备(例如鼠标、键盘、磁盘、屏幕、调制解调器和打印机)的输入和输出都是用流来处理的,在C语言中,所有的流均以文件的形式出现——不一定是物理磁盘文件,还可以是对应于某个输入/输出源的逻辑文件。C语言提供了5种标准的流,你的程序在任何时候都可以使用它们,并且不必打开或者关闭它们。(以下列出了这5种标准的流。

     名称        描述              例子

  1. stdin     标准输入         键盘
  2. stdout     标准输出          屏幕
  3. stderr    标准错误          屏幕
  4. stdprn     标准打印机       LPT1端口
  5. stdaux     标准串行设备     COM1端口

如图:

2.

先将一个文件写入点内容:

fgets是有点坑的,首先它要求缓冲区的buf要是字符数组,如果定义为字符指针要用malloc指定大小,然后,fgets是遇到结束符\0才停下,所以在初始化的时候显示加上结束符。

调试物语:当你遇到花尽毕生所学都解决不了的问题的时候,这必定是自己疏忽造成的弱智问题,一定要检查代码细小的地方,看看是弱智漏了那个符号。

3.

可以看到如果按照&item的写法,将整个结构体内容写过去是写成了二进制文件,应该改为用fprintf来完成输出到文件中。

实验代码:

4.

#include <stdlib.h>
#include <stdio.h>
#define BUFFER_SIZE 50
int main(int argc,char **argv)
{
        FILE *from_fd ,*to_fd;//文件指针的定义
        long len;
        char buffer[BUFFER_SIZE];
        int ret;//记录文件读取的长度
        if(argc!=3)
        {
                printf("argument is not enough\n");
                return -1;
        }
        if((from_fd=fopen(argv[1],"a+b"))==NULL)//以追加可读可写的方式打开文件,若文件不存在就新建文件
        {
                printf("file not exist\n");
                return -1;
        }
        fprintf(from_fd,"hello\n");//为文件写入数据
        if((to_fd=fopen(argv[2],"w+b"))==NULL)
        {
 
                printf("file not create\n");
                return -1;
        }
        //获取要复制的文件长度
        fseek(from_fd,0L,SEEK_END);//把文件指针放置在文件的末尾,然后获取文件的长度
        len=ftell(from_fd);//获取文件的长度
        fseek(from_fd,0L,SEEK_SET);//
        while(!feof(from_fd))//判断文件指针是否到文件末尾
        {
                //读文件
                fread(buffer,BUFFER_SIZE,1,from_fd);//返回一次读取文件的大小
                if(bUFFER_SIZE>=len)//若文件长度已经减小至比返回值小,此时已读取完文件
                {
                        fwrite(buffer,len,1,to_fd);
                }else
                {
                        fwrite(buffer,BUFFER_SIZE,1,to_fd);
                        len-=BUFFER_SIZE;//记录还需复制的文件长度
                }
                bzero(buffer,BUFFER_SIZE);//清空缓冲区的内容
        }
        fclose(from_fd);
        fclose(to_fd);
        exit(0);
 
 
}

5.

localtime函数:

C 库函数 struct tm *localtime(const time_t *timer) 使用 timer 的值来填充 tm 结构。timer 的值被分解为 tm 结构,并用本地时区表示。

timer值用time函数获取:

C 库函数 time_t time(time_t *seconds) 返回自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的时间,以秒为单位。如果 seconds 不为空,则返回值也存储在变量 seconds 中。

注意一点,特别是传参是结构体型的参数,不要传指针,因为指针变量大小是固定的,并且没有初始化。如果要传指针就要先初始化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值