C++20: 像Python一样逐行读取文本文件并支持切片操作

server/2024/12/2 13:14:27/

概要

逐行读取文本文件,并提取其中连续的几行,这对于 Python 来说是小菜一碟。 C++ 则很笨拙, 语言不自带这些。 这次我来拯救 C++ boys & girls, 在 C++20 环境下,山寨一个 Python 下的逐行读文本文件、支持 slice 操作的代码,包含基础设施的实现和调用实例代码。

问题是什么?

data.csv

0,11,336,23,370
0,5,370,16,404
1,370,404,410,419
1,435,376,444,402
2,249,409,280,446
2,579,441,632,472
python">filepath = "data.csv"with open(filepath, "r") as f:# print('type(f):', type(f))lines = f.readlines()for line in lines[1:3]:print(line.strip())print('---')for line in lines[3:]:print(line.strip())

对于上述文本文件和 Python 代码, 用 C++20 实现一个等效的代码:

  • 基础设施代码,不限制行数
  • 调用代码,尽可能和 Python 代码长得像, 比如都是10行以内,切片操作也尽可能的直观

逐行读取文件 - C++ 实现

这个功能比较好实现,返回 vector 就可以了。文件读取使用的是 std::fstream,基于 RAII 思想创建和释放。对于每一行文本的读取,使用 std::getline() 来完成。

#include <fstream>
#include <vector>
#include <string>class TextIOWrapper
{
public:TextIOWrapper(const std::string& filepath){ifs.open(filepath);}~TextIOWrapper(){ifs.close();}std::string readline(){std::string line;std::getline(ifs, line);return line;}std::vector<std::string> readlines(){std::vector<std::string> lines;std::string line;while (std::getline(ifs, line)){lines.emplace_back(line);}return lines;}private:std::ifstream ifs;
};

切片操作 - 基于C++20的实现

对于切片操作: Python 中的 [start:end], C++ 里并不支持; std::ranges 使用的管道操作符 |,可以用作这个目的。

std::ranges 笨拙的地方在于,只提供了 std::ranges::views::drop(start)std::ranges::views::take(end-start) 这样的基础操作,从来不考虑调用者用起来多费劲。。。那么我们自行封装一个:


namespace views {auto slice(size_t start, size_t end) {return std::ranges::views::drop(start) | std::ranges::views::take(end - start);}auto slice(size_t start) {return std::ranges::views::drop(start);}
}

调用代码 - C++

在这里插入图片描述

#include <iostream>int main()
{const std::string filepath = "data.csv";TextIOWrapper fin(filepath);auto lines = fin.readlines();for (auto line : lines | views::slice(1, 3)){std::cout << line << std::endl;}printf("---\n");for (auto line : lines | views::slice(3)){std::cout << line << std::endl;}return 0;
}

完整代码

https://github.com/zchrissirhcz/clumsy/commit/9273ccaf50c31a5b0c2190713dd696c7d0d200f4

总结

本文从简洁的 Python 读取文本文件和切片的代码出发,以相同简洁的调用代码为目标,使用常规的 C++ 封装方式实现了返回文件所有行或单独一行的操作;然后基于 C++20 的 std::ranges 实现了类似 Python 中的切片操作, 并给出了示例代码来展示正确性。

参考

https://stackoverflow.com/questions/50549611/slicing-a-vector-in-c


http://www.ppmy.cn/server/146726.html

相关文章

【C++】 list接口以及模拟实现

list介绍 list文档介绍 C中的list是一个双向链表容器。它允许在任意位置进行快速插入和删除操作&#xff0c;并且能够在常量时间内访问任意元素&#xff0c;并且该容器可以前后双向迭代。 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容…

arcgis for js FeatureLayer和GeoJSON一个矢量点同时渲染图形和文本

效果 FeatureLayer和GeoJSONLayer, 一个矢量点同时渲染图形和文本 代码 相关参数自行查阅文档, 这里就不做注释了 示例代码手动创建FeatureLayer方式, 如果是通过远程url加载图层的 渲染方式同理, GeoJSONLayer同理 <!DOCTYPE html> <html lang"zn"><…

[极客时间]AIGC产品经理训练营毕业总结

为期10周的训练营也进入尾声了,回想当初&#xff0c;真的是蛮感慨的。 我为什么会去参加AIGC产品训练营呢? 其实也是蛮奇妙的. 我是一名传统业务的前端研发, 因为一个项目第一次真实的接触到了AIGC,就感觉像是打开了新世界的大门,让我倍感兴奋,想要在ai的世界里探索一番. 不过…

数学建模选MATLAB还是Python?

在进行数学建模时&#xff0c;选择合适的编程语言和工具对于建模的效率和效果至关重要。目前&#xff0c;MATLAB和Python是两个常用的数学建模工具&#xff0c;它们各自有优缺点&#xff0c;适用于不同的场景。本文将从多个维度对MATLAB和Python进行比较&#xff0c;帮助大家做…

git的使用(简洁版)

什么是 Git&#xff1f; Git 是一个分布式版本控制系统 (DVCS)&#xff0c;用于跟踪文件的更改并协调多人之间的工作。它由 Linus Torvalds 在 2005 年创建&#xff0c;最初是为了管理 Linux 内核的开发。Git 的主要目标是提供高效、易用的版本控制工具&#xff0c;使得开发者…

用c语言完成俄罗斯方块小游戏

用c语言完成俄罗斯方块小游戏 这估计是你在编程学习过程中的第一个小游戏开发&#xff0c;怎么说呢&#xff0c;在这里只针对刚学程序设计的学生&#xff0c;就是说刚接触C语言没多久&#xff0c;有一点功底的学生看看&#xff0c;简陋的代码&#xff0c;简陋的实现&#xff0…

Milvus的索引类型

Milvus 是一个开源的向量数据库&#xff0c;专为高效存储、检索和管理大规模向量数据而设计。Milvus 提供了多种索引类型&#xff0c;用于加速向量搜索的性能&#xff0c;不同的索引类型适用于不同的数据特性、查询需求和硬件资源。下面是 Milvus 支持的主要索引类型的详细介绍…

React Router

概述 React Router 创建于 2014 年&#xff0c;是一个用于 React 的声明式、基于组件的客户端和服务端路由库&#xff0c;它可以保持 UI 与 URL 同步&#xff0c;拥有简单的 API 与强大的功能。 安装依赖 // npm npm install react-router-dom6// pnpm pnpm add react-route…