文件I/O练习题第二天

练习:要求利用标准IO 函数接口实现计算一个本地磁盘某个文件的大小,要求文件名称通
过命令行进行传递,并进行验证是否正确( ls -l)。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    // 1.要求要计算大小的文件的路径需要通过命令行传递给main(),需要判断用户传递的参数是否有效
    if (2 != argc)
    {
        printf("argument is invalid!\n");
        exit(1);
    }

    // 2.利用fopen()以只读方式打开需要计算大小的文件 "rb" 以二进制方式打开文件
    FILE *fp = fopen(argv[1], "rb");
    if (NULL == fp)
    {
        perror("fopen file error");
        exit(1);
    }

    // 3.计算文本数据大小,可以采用循环计数的方式,每次从文本中读取一个字符,直到文本到达末尾
    int cnt = 0;
    while (1)
    {
        if (fgetc(fp) == EOF)
        {
            printf("end of file\n");
            break;
        }
        cnt++;
    }

    // 4.循环终止,则说明计算完成,此时输出文本大小即可
    // printf("file [%s]: size = %ld \n", argv[1], ftell(fp)); // 第二种方法,简单
    printf("file [%s]: size = %d \n", argv[1], cnt);

    // 5.关闭文件
    fclose(fp);

    return 0;
}

练习:利用标准IO 函数接口实现文件拷贝,把本地磁盘的文件A 中的数据完整的拷贝到另
一个文本B 中,如果文本B 不存在则创建,要求文本A 的名称和文本B 的名称通过命令行
传递,并进行验证是否正确。

#include <stdio.h>
#include <strings.h>
#include <stdlib.h>


//用户缓冲区的大小
#define  BUFFERSIZE	 512   

int main(int argc, char const *argv[])
{
	int src_size = 0; //记录待拷贝文件的大小
	int loop_cnt = 0; //循环次数
	int remainder= 0; //记录剩余字节数量

	//1.由于待拷贝文件的路径需要通过命令行传递,则需要分析命令行参数数量是否符合需求
	if (3 != argc)
	{
		printf("argument is invaild\n");
		exit(1);
	}

	//2.则分别打开待拷贝文件(rb)和目标文件(wb)
	FILE *src_fp = fopen(argv[1],"rb");	
	if (NULL == src_fp)
	{
		printf("fopen %s is error\n", argv[1]);
		exit(1);
	}

	FILE *dest_fp = fopen(argv[2],"wb");	
	if (NULL == dest_fp)
	{
		printf("fopen %s is error\n", argv[2]);
		exit(1);
	}

	//3.为了提高程序的运行效率,采用空间换时间的思想,定义数据缓冲区来存储文件数据
	char data_buffer[BUFFERSIZE] = {0};

	fseek(src_fp,0,SEEK_END); //偏移待拷贝文件的光标到文件末尾
	src_size = ftell(src_fp); //统计待拷贝文件的大小
	fseek(src_fp,0,SEEK_SET); //偏移待拷贝文件的光标到文件开头

	printf("src file size = %d\n",src_size);

	//4.计算需要读取数据块的次数,循环写入到目标文件中即可     
	loop_cnt = src_size / BUFFERSIZE;
	remainder= src_size % BUFFERSIZE;

	while(loop_cnt--)
	{
		//从待拷贝文件中读取数据
		fread(data_buffer,BUFFERSIZE,1,src_fp);
		//向目标文件中写入数据块
		fwrite(data_buffer,BUFFERSIZE,1,dest_fp);
	}

	//5.分析待拷贝文件是否存在剩余未拷贝的数据,如果存在,则再拷贝依次即可
	if (remainder > 0)
	{	
		//需要提前清空数据缓冲区
		bzero(data_buffer,BUFFERSIZE);

		//从待拷贝文件中读取数据
		fread(data_buffer,remainder,1,src_fp);

		//向目标文件中写入数据块
		fwrite(data_buffer,remainder,1,dest_fp);
	}

	//6.为了验证是否拷贝完成,则统计目标文件的数据量
	printf("dest file size = %d\n",ftell(dest_fp));

	//7.完成拷贝动作,则需要分别关闭两个文件
	fclose(src_fp);
	fclose(dest_fp);

	return 0;
}

作业:设计程序,获取当前系统时间,把时间转换为特定格式”yy 年mm 月dd 日星期x
tt:mm:ss”,并每隔1s 写入到本地磁盘中一个叫做log.txt 的文本中,如果文本不存在则创建。

#include <stdio.h>
#include <time.h>
#include <unistd.h>  // for sleep()

int main() {
    // 打开日志文件(不存在则创建,追加模式)
    FILE *log_file = fopen("log.txt", "a");
    if (log_file == NULL) {
        perror("无法打开日志文件");
        return 1;
    }

    // 星期几的中文表示
    const char *weekdays[] = {"日", "一", "二", "三", "四", "五", "六"};

    while (1) {
        // 获取当前时间
        time_t raw_time;
        struct tm *time_info;
        time(&raw_time);
        time_info = localtime(&raw_time);

        // 格式化时间字符串
        char time_str[50];
        strftime(time_str, sizeof(time_str), "%y年%m月%d日", time_info);
        
        // 组合完整的时间字符串
        fprintf(log_file, "%s星期%s %02d:%02d:%02d\n", 
                time_str,
                weekdays[time_info->tm_wday],
                time_info->tm_hour,
                time_info->tm_min,
                time_info->tm_sec);
        
        // 刷新缓冲区确保立即写入文件
        fflush(log_file);
        
        // 等待1秒
        sleep(1);
    }

    // 理论上不会执行到这里
    fclose(log_file);
    return 0;
}
posted @ 2025-07-24 23:27  九思0404  阅读(15)  评论(0)    收藏  举报