【ARM 嵌入式 C 文件操作系列 20.1 -- 从 A文件的 n 行开始 拷贝 m行到 B文件中】


请阅读【嵌入式开发学习必备专栏 】


文章目录

    • 文件行拷贝
      • 根据行数大小设定拷贝方法
      • 拷贝每行固定字符个数的方式

文件行拷贝

从文件 a 中从第 n 行开始拷贝 m 行到文件 b 的函数,将需要使用标准库函数来读取和写入文件。以下是一个 file_copy_lines 函数实现:

#include <stdio.h>
#include <stdlib.h>void file_copy_lines(const char *src_filename, const char *dest_filename, int n, int m) 
{FILE *src = fopen(src_filename, "r");FILE *dest = fopen(dest_filename, "w");if (src == NULL || dest == NULL) {fprintf(stderr, "Error opening files.\n");exit(EXIT_FAILURE);}char buffer[1024]; // 假设一行最大长度为 1023 字符int current_line = 0;// 跳过前 n-1 行while (current_line < n - 1 && fgets(buffer, sizeof(buffer), src) != NULL) {current_line++;}// 拷贝 m 行到目标文件while (current_line < n + m - 1 && fgets(buffer, sizeof(buffer), src) != NULL) {fputs(buffer, dest);current_line++;}fclose(src);fclose(dest);
}int main(void) 
{const char *src_filename = "a.txt";const char *dest_filename = "b.txt";int start_line = 2; // 从第二行开始拷贝int num_lines = 3; // 拷贝三行file_copy_lines(src_filename, dest_filename, start_line, num_lines);return 0;
}

这个 file_copy_lines 函数接收四个参数:源文件名 src_filename,目标文件名 dest_filename,起始行号 n,以及要拷贝的行数 m。它首先尝试打开源文件和目标文件,并在无法打开时报错退出。

函数使用 fgets 来读取每一行,利用 buffer 数组作为中介存储每行的内容。如果当前行号小于 n-1,它会继续读取;当行号达到 n-1 时,它开始将内容写入目标文件,直到拷贝了 m 行内容。最后,函数关闭了两个打开的文件。

这个例子假设了每行的最大长度为 1023 字符(加上一个空终止符,总共 1024 字符)。如果预计有更长的行,需要根据需要调整 buffer 的大小。此外,fgets 会读取换行符并将其包含在结果字符串中,因此整行内容(包括换行符)都会被写入目标文件。如果源文件的最后一行长度超过 buffer 的大小,fgets 可能不会一次性读取完整行,可能需要特别处理。

根据行数大小设定拷贝方法

从文件 a.txt 中拷贝指定行数的内容,如果 lines 小于等于 100,它将一次性拷贝所有行;如果 lines 大于 100,它将每次拷贝 100 行,直到拷贝完 lines 行。

#include <stdio.h>
#include <stdlib.h>void copy_lines(const char *src_filename, int start_line, int lines) 
{FILE *src = fopen(src_filename, "r");if (src == NULL) {perror("Error opening source file");exit(EXIT_FAILURE);}FILE *dest = fopen("b.txt", "w");if (dest == NULL) {perror("Error opening destination file");fclose(src); // 关闭已经打开的源文件exit(EXIT_FAILURE);}char buffer[1024]; // 假设一行最大长度为 1023 字符int current_line = 0;int lines_to_copy = lines > 100 ? 100 : lines; // 每次最多拷贝 100 行while (current_line < start_line - 1 && fgets(buffer, sizeof(buffer), src) != NULL) {current_line++; // 跳过前 start_line-1 行}while (lines > 0 && fgets(buffer, sizeof(buffer), src) != NULL) {fputs(buffer, dest); // 拷贝一行到目标文件lines--;current_line++;if (current_line % 100 == 0 && lines > 0) {fclose(dest); // 关闭当前的目标文件,每 100 行后重新打开dest = fopen("b.txt", "a");if (dest == NULL) {perror("Error reopening destination file");fclose(src);exit(EXIT_FAILURE);}lines_to_copy = lines > 100 ? 100 : lines; // 更新剩余行数}}fclose(src);fclose(dest);
}
int main(void) 
{const char *src_filename = "a.txt";int start_line = 1; // 从第一行开始拷贝int num_lines = 250; // 拷贝 250 行copy_lines(src_filename, start_line, num_lines);return 0;
}

这个 copy_lines 函数会根据 lines 的值来决定拷贝行为。它首先尝试打开源文件 a.txt 和目标文件 b.txt。如果遇到错误,它会打印错误信息并退出程序。

函数使用 fgets 读取每一行,并使用 fputs 将这些行写入目标文件。为了拷贝从特定行开始的内容,它首先跳过 start_line - 1 行。然后开始拷贝,如果行数超过 100,它将关闭目标文件,然后重新以追加模式打开,从而每次最多拷贝 100 行,直到完成 lines 行的拷贝。

请确保在运行程序前,源文件 a.txt 存在于同一目录中,并且有足够的行供程序读取。如果源文件的某一行超出了缓冲区 buffer 的大小(在本例中为 1024 字符),fgets 可能会分多次读取该行,可能需要调整缓冲区大小或进行特殊处理以确保每行都被完整读取。

拷贝每行固定字符个数的方式

下面是一个 C 语言函数的实现,该函数打开文件 a.txt,定位到第 n 行,然后从第 n 行开始复制 m 行数据,每行有固定的 32 个字符:

#include <stdio.h>
#include <stdlib.h>
void copy_fixed_length_lines(const char *src_filename, const char *dest_filename, int n, int m) 
{FILE *src = fopen(src_filename, "r");if (src == NULL) {perror("Error opening source file");exit(EXIT_FAILURE);}FILE *dest = fopen(dest_filename, "w");if (dest == NULL) {perror("Error opening destination file");fclose(src); // 关闭已经打开的源文件exit(EXIT_FAILURE);}int current_line = 0;int copied_lines = 0;char buffer[33]; // 32个字符加上终结符 '\0'// 跳过前 n-1 行while (current_line < n - 1 && fgets(buffer, sizeof(buffer), src) != NULL) {current_line++;}// 从第 n 行开始复制 m 行数据while (copied_lines < m && fgets(buffer, sizeof(buffer), src) != NULL) {// 如果读到的行不足32个字符,则使用空格填充buffer[32] = '\0'; // 确保字符串的结束if (strlen(buffer) < 32) {memset(buffer + strlen(buffer) - 1, ' ', 32 - strlen(buffer));}fprintf(dest, "%.32s\n", buffer); // 将缓冲区的前32个字符写入目标文件copied_lines++;}fclose(src);fclose(dest);
}int main(void) 
{const char *src_filename = "a.txt";const char *dest_filename = "b.txt";int start_line = 3; // 从第三行开始复制int num_lines = 5; // 复制五行copy_fixed_length_lines(src_filename, dest_filename, start_line, num_lines);return 0;
}

这个 copy_fixed_length_lines 函数使用 fopen 分别以读模式 ("r") 打开源文件 a.txt 和写模式 ("w") 打开目标文件 b.txt。如果源文件或目标文件打开失败,函数打印错误信息并退出。
函数首先跳过 n - 1 行,然后开始复制 m 行数据。每次从文件中读取的内容使用 fgets 存储到 buffer 中,该缓冲区大小为 33 字节,为了确保存储 32 个字符加上一个 null 终止符。由于 fgets 会读取并包含换行符(如果有的话),所以如果读取的行不足 32 个字符,使用 memset 在行末填充空格,直到达到 32 个字符。然后,使用 fprintf 写入刚好 32 个字符到目标文件,并追加一个换行符。

如果源文件的任何行长度超过了 32 个字符,此函数将只复制每行的前 32 个字符。如果源文件的任何行长度不足 32 个字符,将用空格填充至 32 个字符。如果源文件中的行数少于 n,或者从第 n 行开始的行数少于 m,那么函数只复制可用的行数。

最后,函数关闭了打开的文件。在实际使用中,可能需要调整 buffer 的大小或函数的逻辑来匹配不同长度的行或不同的复制策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/792637.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DO、DTO、BO、VO、PO、DAO、POJO

目录 一、DO、DTO、BO、VO、PO、DAO、POJO的概念 二、DO、DTO、BO、VO具体如何使用&#xff1f;代码详细说明 三、有没有其他类似的概念&#xff0c;比如POJO&#xff08;Plain Old Java Object&#xff09;&#xff1f;它们有什么区别&#xff1f; 四、在实际项目中&#…

[lesson05]引用的本质分析

引用的本质分析 引用的意义 引用作为变量别名而存在&#xff0c;因此在一些场合可以代替指针 引用相对于指针来说具有更好的可读性和实用性 注意&#xff1a; 函数中的引用形参不需要进行初始化&#xff01;&#xff01; 特殊的引用 const引用 在C中可以声明const引用 cons…

可能是最便宜的姿态传感器,国产三轴加速度计SC7A20

可能是最便宜的姿态传感器 三轴检测 批量参考价格&#xff1a;整盘单价&#xff1a;1.242&#xff0c;一个包装10K&#xff0c;希望厂家能出点数量少的包装&#xff0c;这一盘太多了&#xff1a;&#xff09; 特点 宽电压范围 1.71V-3.6V 1.8V 兼容数字 IO 口 低功耗模式下…

若依项目名、包名修改器

Updater.java import java.io.File; import java.util.*;public class Updater {public static void main(String[] args) {String projectPath"D:\\workspace\\idea\\RuoYi-Cloud-Plus-2.X";updateNames(new File(projectPath));}//需要改名的目录名称&#xff08;…

GNURadio 软件在windows环境下安装

一、软件下载 网址&#xff1a;InstallingGR - GNU Radio 我已经下载的软件安装包&#xff0c;radioconda-2024.01.26-Windows-x86_64.rar 网址&#xff1a;https://download.csdn.net/download/weixin_37728585/89082238 二、安装过程 所有用户均可以使用。 选择安装路径&a…

一文彻底搞清 Iterator(遍历器)概念及用法

目录 一、由来及意义 二、具体实现流程 三、具有默认 Iterator 接口的数据结构 四、调用 Iterator 接口的场合 五、总结 一、由来及意义 Javascript中表示“集合”的数据结构&#xff0c;主要是 Array、Object、Map、Set 这四种数据集合&#xff0c;除此之外&#xff0c;…

每日一题 --- 删除字符串中的所有相邻重复项[力扣][Go]

删除字符串中的所有相邻重复项 题目&#xff1a;1047. 删除字符串中的所有相邻重复项 给出由小写字母组成的字符串 S&#xff0c;重复项删除操作会选择两个相邻且相同的字母&#xff0c;并删除它们。 在 S 上反复执行重复项删除操作&#xff0c;直到无法继续删除。 在完成所…

JVM基础二——类的生命周期

加载阶段 &#xff1a; 连接阶段&#xff1a; 初始化阶段&#xff1a; 总结&#xff1a;

【Linux】SSH协议应用

SSH协议 SSH简介实现OpenSSH ssh中的四个文件~/.ssh文件路径实验解析 SSH 简介 SSH&#xff08;secure shell&#xff09;只是一种协议&#xff0c;存在多种实现&#xff0c;既有商业实现&#xff0c;也有开源实现。本文针对的实现是OpenSSH&#xff0c;它是自由软件&#xf…

React三大组件--ref

1.定义&#xff1a;组件内的标签可以定义ref属性来标识自己。 2.使用ref的三种方法 字符串形式的ref &#xff08;这个写法会慢慢替换掉&#xff0c;所以尽量不要写字符串形式&#xff09; <!DOCTYPE html> <html lang"en"> <head><meta cha…

第18讲:数据在内存中的存储

⽬录 1. 整数在内存中的存储 2. ⼤⼩端字节序和字节序判断 3. 浮点数在内存中的存储 ——————————————————————————————————————————— 1. 整数在内存中的存储 在讲解操作符的时候&#xff0c;我们就讲过了下⾯的内容&#x…

力扣热题100_链表_21_合并两个有序链表

文章目录 题目链接解题思路解题代码 题目链接 21. 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例…

jupyter Notebook 默认路径修改

1. anaconda prompt 中运行 jupyter notebook --generate-config 命令&#xff0c;将在 C:\Users\Think\.jupyter文件下生成 jupyter_notebook_config.py 文件。 2.在jupyter_notebook_config.py 文件中&#xff0c;找c.NotebookApp.notebook_dir 这个变量&#xff0c; (1)若…

Solana 线下活动回顾|多方创新实践,引领 Solana“文艺复兴”新浪潮

Solana 作为在过去一年里实现突破式飞跃的头部公链&#xff0c;究竟是如何与 Web3 行业共振&#xff0c;带来全新的技术发展与生态亮点的呢&#xff1f;在 3 月 24 日刚结束的「TinTin Destination Moon」活动现场&#xff0c;来自 Solana 生态的的专家大咖和 Web3 行业的资深人…

Java生产者消费者模式(等待唤醒机制)

1.生产者消费者模式 生产者消费者模式是一个十分经典的多线程协作的模式&#xff0c;主要用于解决多线程间的同步问题。它描述了两个类之间的协作&#xff1a;生产者和消费者。生产者负责生成数据&#xff08;或称为“产品”&#xff09;&#xff0c;而消费者负责消费这些数据…

LeetCode - 移除石子使总数最小

1962. 移除石子使总数最小 当我看到这道题目的时候&#xff0c;第一时间想到的是&#xff1a;while循环 sort&#xff0c;时间复杂度 k*nlogn。题目要求执行k次操作后&#xff0c;剩下狮子的最小总数&#xff0c;我们是否可以考虑维护一个堆呢&#xff1f;堆顶值最大&#xff…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《台风灾害下考虑多类型故障不确定性的源网荷协同弹性提升模型》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Leetcode_2两数相加

文章目录 前言一、两数相加1.1 问题描述1.2 解法一&#xff1a;分别将链表转为数字&#xff0c;然后相加1.3 代码实现1.4 解法二&#xff1a;分别将对应位置数字相加1.5 代码实现 二、使用步骤1.引入库2.读入数据 前言 链表是一种物理内存非连续存储&#xff0c;非顺序的线性数…

AI论文速读 |【综述】 时序分析基础模型:教程与综述

论文标题&#xff1a;Foundation Models for Time Series Analysis: A Tutorial and Survey 作者&#xff1a; Yuxuan Liang&#xff08;梁宇轩&#xff09;, Haomin Wen&#xff08;温浩珉&#xff09;, Yuqi Nie&#xff08;PatchTST一作&#xff09;, Yushan Jiang, Ming J…

windows安装Openssl

openssl官网:[ Downloads ] - /source/index.html Windows 安装方法 OpenSSL 官网没有提供 Windows 版本的安装包&#xff0c;可以选择其他开源平台提供的工具 Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions 等待下载完成 捐不起 配置环境变量 ope…