C++文件操作实战:从基础逐行读取到CSV解析与性能优化
1. 项目概述为什么文件操作是C的必修课如果你正在为期末大作业或者毕业设计发愁尤其是那些需要处理数据文件、日志分析或者配置读取的任务那么“文件操作”这个坎儿你大概率是绕不过去的。我见过太多同学C语法学得挺溜一到要读写文件就懵了要么是数据读不进来要么是写出去的文件乱码调试起来一头雾水。其实文件操作远没有想象中那么复杂它就像是程序与外部世界你的硬盘沟通的桥梁。掌握了它你的程序就不再是孤岛可以从文件中加载初始数据可以把运行结果持久化保存甚至能处理海量的数据集。这次我们就聚焦在“逐行读取”这个最经典、最高频的需求上从最基础的ifstream讲起一直深入到处理复杂格式、大文件以及实际项目中的避坑技巧。无论你是想快速搞定一个课程设计还是为毕设的数据处理模块打下基础这篇内容都能给你一套清晰、可直接“抄作业”的方案。2. 核心思路与工具选型为什么是fstream面对文件操作C标准库提供了好几套工具比如C风格的FILE*配合fopen/fread或者Windows API。但对于我们日常学习和大多数项目来说标准库中的fstream头文件提供的流类ifstream,ofstream,fstream是最佳选择。原因很简单它更“C”。它完美地融入了C的流式I/O体系就像你用cin和cout一样通过运算符重载,和成员函数getline来操作代码写起来更直观类型安全也更好避免了手动管理缓冲区大小和指针偏移那些容易出错的琐事。逐行读取顾名思义就是一次从文件中读取一整行文本直到遇到换行符为止。这特别适合处理配置文件每行一个配置项、日志文件每行一条记录、CSV或TSV格式的数据尽管解析字段还需要进一步处理。我们的核心武器就是std::ifstream输入文件流和std::getline()函数。整个流程可以概括为打开文件 - 检查是否成功打开 - 循环读取每一行 - 处理每一行的内容 - 关闭文件。虽然文件流在析构时会自动关闭但显式调用close()是一个好习惯尤其是在需要立即释放文件锁或检查关闭状态的时候。注意很多新手会混淆ifstream的运算符和getline。是按空白字符空格、制表符、换行分割读取的它读不了包含空格的整行句子。而getline才是真正读取一行包括其中的空格直到遇到换行符为止。这是第一个需要区分的重点。3. 从零开始你的第一个逐行读取程序理论说再多不如动手写一遍。我们从一个最简单的例子开始目标是读取一个名为data.txt的文本文件并将其内容逐行打印到控制台。3.1 基础代码实现首先你需要确保有一个data.txt文件里面随便写几行文字和你的C源码放在同一个目录下这样可以使用相对路径。当然使用绝对路径如C:\\Users\\Name\\data.txt注意Windows下是双反斜杠或单正斜杠也可以但可移植性会变差。#include iostream #include fstream // 核心头文件 #include string int main() { // 1. 创建输入文件流对象并尝试打开文件 std::ifstream inputFile(data.txt); // 2. 至关重要的步骤检查文件是否成功打开 if (!inputFile.is_open()) { std::cerr 错误无法打开文件 data.txt std::endl; std::cerr 请检查1)文件是否存在2)路径是否正确3)是否有读取权限。 std::endl; return 1; // 非零返回值通常表示程序异常结束 } std::string line; // 用于存储每一行内容的字符串 int lineNumber 0; // 可选行号计数器便于调试 // 3. 核心循环逐行读取 while (std::getline(inputFile, line)) { lineNumber; std::cout 第 lineNumber 行: line std::endl; // 在这里你可以对 line 字符串进行任何处理 // 例如解析、计算、筛选等。 } // 4. 关闭文件流良好习惯 inputFile.close(); // 5. 可选判断是否读到文件尾还是中途因错误退出 if (inputFile.eof()) { std::cout 已成功读取到文件末尾。 std::endl; } else if (inputFile.fail()) { std::cerr 读取过程中发生错误非EOF错误。 std::endl; } return 0; }3.2 关键点解析与避坑指南这段简单的代码里藏着几个新手必踩的坑第一坑不检查文件是否打开成功。这是最常见的错误。直接假设文件存在并开始读如果文件不存在或路径错误后续的getline操作会失败但程序可能不会立即崩溃而是产生难以预料的行为比如line变量保持为空或上一次的值。所以if (!inputFile.is_open())这个检查绝对不能省。第二坑文件路径问题。在IDE如VS Code、Visual Studio、CLion中运行你的“当前工作目录”不一定是源码所在目录。对于简单项目把数据文件和可执行文件放在一起最省事。更健壮的做法是使用filesystem库C17来构造或检查路径或者让用户通过命令行参数输入文件路径。第三坑混淆while(getline(...))和while(!inputFile.eof())。后者是错误的用法eof()标志是在尝试读取超过文件末尾后才被设置的。如果你用while(!inputFile.eof()) { getline(...); ... }循环会多执行一次导致最后一次处理的是无效数据。而while(getline(...))的写法是安全的因为getline函数本身在失败包括到达文件尾时会返回一个可转换为false的流对象。第四坑忽略行的结尾字符。std::getline默认的终止符是换行符\n它会读取换行符之前的所有字符并丢弃这个换行符。所以line字符串里是不包含行尾的\n的。如果你需要保留确切的换行符或者处理Windows格式\r\n需要了解这一点。getline的第三个参数可以指定自定义终止符。4. 进阶实战处理复杂场景与数据解析只会把行打印出来远远不够。期末作业或毕设里你面对的更可能是结构化的数据。我们来看几个升级场景。4.1 场景一解析CSV格式数据逗号分隔值假设grades.csv文件内容如下姓名,学号,C成绩,高数成绩 张三,2023001,85,90 李四,2023002,92,88 王五,2023003,78,85我们需要读取它并计算每个学生的平均分。#include iostream #include fstream #include string #include sstream // 引入字符串流用于分割字符串 int main() { std::ifstream file(grades.csv); if (!file.is_open()) { std::cerr 打开文件失败 std::endl; return 1; } std::string header; std::getline(file, header); // 读取并跳过标题行 std::cout 标题行: header std::endl; std::string line; while (std::getline(file, line)) { // 使用std::istringstream将一行字符串转换为流便于用getline分割 std::istringstream lineStream(line); std::string name, id, cppGradeStr, mathGradeStr; // 使用getline并指定分隔符为逗号 std::getline(lineStream, name, ,); std::getline(lineStream, id, ,); std::getline(lineStream, cppGradeStr, ,); std::getline(lineStream, mathGradeStr); // 最后一列不需要指定分隔符 // 将字符串转换为整数 // 在实际项目中这里需要添加错误处理如stoi可能抛出异常 int cppGrade std::stoi(cppGradeStr); int mathGrade std::stoi(mathGradeStr); double average (cppGrade mathGrade) / 2.0; std::cout 学生: name (学号: id ), 平均分: average std::endl; } file.close(); return 0; }实操心得处理外部数据永远不要相信数据是完美的。上面的代码假设每一行都有4个字段且成绩都是有效数字。但在现实中文件可能有空行、字段缺失、数字格式错误等。健壮的代码应该用try-catch包裹std::stoi并在每次getline后检查lineStream的状态。对于复杂的CSV如字段内包含逗号或引号建议使用专门的库如fast-cpp-csv-parser。4.2 场景二逐行处理并写入新文件日志过滤这是另一个常见需求从一个庞大的日志文件server.log中筛选出包含“ERROR”关键词的行并保存到errors.txt中。#include iostream #include fstream #include string int main() { std::ifstream logFile(server.log); std::ofstream errorFile(errors.txt); // 创建输出文件流 if (!logFile.is_open()) { std::cerr 无法打开日志文件 std::endl; return 1; } if (!errorFile.is_open()) { // 同样需要检查输出文件 std::cerr 无法创建错误日志文件 std::endl; logFile.close(); return 1; } std::string line; while (std::getline(logFile, line)) { // 使用std::string的find方法查找子串 // 如果找不到find会返回std::string::npos if (line.find(ERROR) ! std::string::npos) { errorFile line std::endl; // 写入到新文件 // 也可以同时输出到控制台 std::cout 发现错误: line std::endl; } } logFile.close(); errorFile.close(); // 记得关闭输出流确保缓冲区数据写入磁盘 std::cout 错误日志筛选完成已保存至 errors.txt。 std::endl; return 0; }注意事项输出文件流std::ofstream在打开文件时默认模式会清空已存在的文件内容。如果你希望追加写入而不是覆盖需要在打开时指定模式std::ofstream errorFile(errors.txt, std::ios::app);。std::ios::app代表追加模式。4.3 场景三处理大文件与性能考量当你的日志文件有几百MB甚至几个GB时简单的逐行读取依然有效但需要注意一些细节以保持程序响应和内存稳定。缓冲区大小ifstream内部有一个缓冲区。对于大文件适当调大缓冲区可以减少I/O系统调用的次数提升速度。但这不是常规优化除非你确实遇到了性能瓶颈。std::ifstream bigFile(huge.log); char buffer[1024 * 1024]; // 1MB的缓冲区 bigFile.rdbuf()-pubsetbuf(buffer, sizeof(buffer));避免不必要的拷贝在while(getline(file, line))循环中line字符串会被反复分配和释放内存。如果只是查找关键词而不需要修改行内容可以考虑使用std::string_viewC17来避免拷贝但这需要配合不同的读取方式。内存占用不要试图用vectorstring把所有行都读进内存。对于超大文件这会导致内存耗尽。始终坚持“流式”处理读一行处理一行丢弃一行或写入输出流。进度反馈处理大文件时给用户一个进度提示是友好的。你可以用file.tellg()获取当前读取位置用file.seekg(0, std::ios::end)和file.tellg()获取文件总大小然后计算百分比。但要注意tellg()对文本文件返回的值不一定就是准确的字节偏移量可能受换行符转换影响对于精确进度以二进制模式打开可能更可靠。5. 常见问题排查与调试技巧实录即使按照“标准答案”写代码在实际运行中还是会遇到各种稀奇古怪的问题。下面是我在带学生和项目实践中总结的一些高频问题及解决方法。5.1 中文乱码问题这是Windows环境下最头疼的问题之一。你的源代码文件、控制台和文本文件的编码可能不一致常见的有GBK和UTF-8。症状读取的中文文件内容在控制台显示为乱码或者写入的中文到文件里是乱码。根因C标准流在Windows上默认使用本地编码如GBK而你的文件或源代码可能是UTF-8。解决方案统一编码最简单的方法是让所有环节都使用同一种编码。对于新项目强烈建议全部使用UTF-8 with BOM在Windows上兼容性更好。可以在VS Code、Visual Studio等编辑器中设置文件编码。转换处理如果必须处理不同编码的文件就需要在读取后或写入前进行转换。这涉及到跨平台编码转换库如iconv或C11的codecvt但后者在C17中被标记为废弃。对于课程作业如果数据量不大统一编码是最省事的。控制台设置Windows命令行(cmd)默认是GBK编码。你可以通过命令chcp 65001临时切换到UTF-8代码页并配合使用支持UTF-8的字体如“Consolas”。在代码中启动程序前执行系统命令system(chcp 65001 nul);也可以但这不是优雅的方案。5.2 文件末尾的空行或多余行症状循环读取后line变量多出一个空字符串或者最后一行数据被处理了两次。排查首先检查你的源文件。很多编辑器如Notepad可以显示所有字符查看文件末尾是否有不可见的换行符。Windows的换行是\r\n而getline默认只认\n可能会把\r留在行尾尤其是在Linux/Mac上创建的文件在Windows上读取时。这会导致字符串比较或输出时末尾多一个回车。解决在处理line之前可以去除其首尾的空白字符包括空格、制表符、回车\r和换行\n。#include algorithm #include cctype #include string // 去除字符串左侧空白 inline void ltrim(std::string s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); })); } // 去除字符串右侧空白 inline void rtrim(std::string s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), s.end()); } // 去除字符串两侧空白 inline void trim(std::string s) { ltrim(s); rtrim(s); } // 在循环中使用 while (std::getline(file, line)) { trim(line); // 去除行首尾空白字符 if (!line.empty()) { // 忽略空行 // 处理非空行 } }5.3 读取性能突然变慢症状处理一个几MB的文件感觉很快但处理一个几百MB的文件时速度越来越慢。排查这可能是因为你在循环内部进行了低效的操作。例如在每一行都std::cout输出到控制台。控制台输出是极其缓慢的I/O操作。或者你在每一行都进行了复杂的字符串拼接line line something这会导致大量的内存重新分配和拷贝。解决减少控制台输出处理大文件时只输出关键信息或进度不要打印每一行。使用或append进行字符串拼接时使用运算符或append()方法通常比运算符效率更高。预分配内存如果你知道字符串大概会增长到多大可以用line.reserve(estimated_size)来预留空间减少重新分配的次数。使用更快的解析方法对于简单的分隔符分割使用std::string::find循环可能比std::istringstream更快。5.4 跨平台路径分隔符问题症状在Windows上写好的代码用了反斜杠\的路径拿到Linux或Mac上编译运行找不到文件。解决C标准库接受正斜杠/作为路径分隔符即使在Windows上。为了代码的跨平台性始终使用正斜杠/。// 好跨平台 std::ifstream file(data/subfolder/config.txt); // 不好仅Windows std::ifstream file(data\\subfolder\\config.txt);对于需要动态构建的复杂路径可以使用C17的std::filesystem::path它能自动处理不同操作系统的分隔符。6. 集成到实际项目一个简单的学生成绩管理系统模块让我们把上面的知识点串起来设想一个毕业设计里可能用到的场景一个学生成绩管理系统的数据加载模块。我们需要从一个格式可能不太规范的文本文件中读取学生成绩进行校验和统计。需求文件input.txt格式不定可能包含空行、注释行以#开头有效数据行格式为姓名:语文成绩,数学成绩,英语成绩。我们需要读取所有有效行计算每个学生的总分和平均分并将结果按总分排序后输出到report.txt。#include iostream #include fstream #include string #include sstream #include vector #include algorithm // for sort struct Student { std::string name; int chinese; int math; int english; int total; double average; // 计算总分和平均分 void calculate() { total chinese math english; average total / 3.0; } // 用于排序的比较函数按总分降序 bool operator(const Student other) const { return total other.total; // 降序 } }; // 辅助函数去除字符串首尾空白 std::string trim(const std::string str) { size_t first str.find_first_not_of( \t\n\r); if (first std::string::npos) return ; size_t last str.find_last_not_of( \t\n\r); return str.substr(first, (last - first 1)); } int main() { std::vectorStudent students; std::ifstream inFile(input.txt); if (!inFile.is_open()) { std::cerr 无法打开输入文件 std::endl; return 1; } std::string line; int lineCount 0; while (std::getline(inFile, line)) { lineCount; line trim(line); if (line.empty() || line[0] #) { continue; // 跳过空行和注释行 } // 解析格式姓名:成绩1,成绩2,成绩3 size_t colonPos line.find(:); if (colonPos std::string::npos) { std::cerr 第 lineCount 行格式错误缺少冒号: line std::endl; continue; } Student stu; stu.name trim(line.substr(0, colonPos)); std::string scoresStr line.substr(colonPos 1); std::istringstream scoreStream(scoresStr); std::string scoreToken; std::vectorint scores; bool parseError false; // 用逗号分割成绩字符串 while (std::getline(scoreStream, scoreToken, ,)) { try { scores.push_back(std::stoi(trim(scoreToken))); } catch (const std::exception e) { std::cerr 第 lineCount 行成绩解析错误: scoreToken std::endl; parseError true; break; } } if (parseError || scores.size() ! 3) { std::cerr 第 lineCount 行成绩数量不正确或格式错误。 std::endl; continue; } stu.chinese scores[0]; stu.math scores[1]; stu.english scores[2]; stu.calculate(); students.push_back(stu); } inFile.close(); // 按总分排序 std::sort(students.begin(), students.end()); // 输出报告 std::ofstream outFile(report.txt); if (!outFile.is_open()) { std::cerr 无法创建报告文件 std::endl; return 1; } outFile 学生成绩报告 std::endl; outFile 排名\t姓名\t语文\t数学\t英语\t总分\t平均分 std::endl; outFile ---------------------------------- std::endl; int rank 1; for (const auto stu : students) { outFile rank \t stu.name \t stu.chinese \t stu.math \t stu.english \t stu.total \t stu.average std::endl; } outFile.close(); std::cout 报告生成完毕共处理 students.size() 条有效记录。 std::endl; return 0; }这个例子综合运用了逐行读取、字符串分割find和getline结合、类型转换stoi、错误处理、数据结构vector和struct以及排序算法。它展示了一个相对健壮的数据处理流程跳过无关行、解析结构化数据、验证数据有效性、处理异常、计算并输出结果。在实际的毕业设计中你可以在此基础上扩展比如从网络获取文件、将数据存入数据库、生成图表等。文件I/O是这一切的数据入口把它写扎实了后面的工作就顺畅多了。

相关新闻

架构实战第3篇:三个文件消灭90%重复代码-泛型CRUD架构解析

架构实战第3篇:三个文件消灭90%重复代码-泛型CRUD架构解析

摘要:在Java企业级开发中,单表CRUD是最常见也是最枯燥的代码。每新增一个业务实体,就要写一套几乎相同的Controller、Service——结构雷同,却又不得不写。《鹿鲸项目管理工具》仅用三个文件——IOneEntityService接口、OneEntityServiceImpl抽…

2026/10/13 8:08:26 阅读更多 →
大学生如何零基础掌握PLC自动化技术?

大学生如何零基础掌握PLC自动化技术?

1. 为什么大学生应该学习PLC自动化技术?工业4.0时代,PLC(可编程逻辑控制器)作为工业自动化的大脑,正在重塑制造业的底层逻辑。对于自动化相关专业的大学生而言,掌握PLC技术不再是加分项,而是必备…

2026/10/13 7:38:28 阅读更多 →
Python实现Playfair密码解密:从古典密码原理到实战脚本开发

Python实现Playfair密码解密:从古典密码原理到实战脚本开发

1. 项目概述:为什么选择Playfair密码? 如果你对古典密码学感兴趣,或者正在学习Python并想找一个兼具趣味性和挑战性的实战项目,那么编写一个Playfair密码的解密脚本绝对是个绝佳的选择。Playfair密码,也称为Playfair S…

2026/10/15 21:28:35 阅读更多 →

最新新闻

Linux日志分析实战:从grep、awk到sed的文本处理全攻略

Linux日志分析实战:从grep、awk到sed的文本处理全攻略

系列写到第九篇,这次我想聊聊日志分析和文本处理相关的那几个命令。前面几篇我们把文件、权限、进程、磁盘、网络都过了一遍,但很多朋友在实际干活时仍然觉得不够用,尤其是系统出了问题需要翻日志的时候,那种“每个命令都认识&…

2026/10/16 3:41:07 阅读更多 →
重装系统后磁盘只剩C盘?分区丢失与数据恢复全指南

重装系统后磁盘只剩C盘?分区丢失与数据恢复全指南

我几乎每个月都能在各类电脑求助帖和身边人的聊天里看到这样一句话:“重装系统之后磁盘只剩一个C盘了,D盘E盘资料全没了,怎么办?”说实话,我第一次遇到这个问题时,第一反应也是心凉了半截。但干这行久了&am…

2026/10/16 3:41:07 阅读更多 →
Ubuntu安装RTX 50系列NVIDIA驱动:runfile实操与避坑指南

Ubuntu安装RTX 50系列NVIDIA驱动:runfile实操与避坑指南

1. 项目概述与方案选型RTX 50 系列发布之后,我身边因为装驱动翻车的案例已经攒了一堆。核心坑点其实很一致:新显卡和老驱动相互不认识,老仓库里又没有新包,最后折腾一晚上还在和黑屏搏斗。所以我打算把 Ubuntu 装 NVIDIA 50 系列驱…

2026/10/16 3:41:07 阅读更多 →
云领数智未来: 《云原生数据库产业发展与行业应用白皮书》重磅发布

云领数智未来: 《云原生数据库产业发展与行业应用白皮书》重磅发布

11月27日,移动云开发者大会在苏州举行。会上,移动云联合IDC重磅发布《云原生数据库产业发展与行业应用白皮书》(以下简称“白皮书”)。该白皮书全面解读了云原生数据库助力企业IT基础设施升级的路径,充分展示了移动云数…

2026/10/16 3:41:07 阅读更多 →
LycheeMem MCP接入教程:3步让任意Agent客户端拥有长期记忆

LycheeMem MCP接入教程:3步让任意Agent客户端拥有长期记忆

【免费下载链接】LycheeMem Lightweight Long-Term Memory for LLM Agents. 项目地址: https://gitcode.com/gh_mirrors/ly/LycheeMem 点击查看 免费下载 LycheeMem 是一款轻量级 LLM Agent 长期记忆框架,本教程带你通过 MCP 协议在 3 步内把它的记忆能…

2026/10/16 3:41:07 阅读更多 →
OpManager Plus 12.5.378 部署避坑指南:Java/OS/DB 环境严丝合缝配置

OpManager Plus 12.5.378 部署避坑指南:Java/OS/DB 环境严丝合缝配置

简介:本资源为ManageEngine OpManager Plus 12.5.378 64位正式版安装包及配套授权文件,面向企业IT运维工程师、网络管理员及中高级系统监控实践者,用于构建统一的网络性能管理平台,解决多工具割裂导致的监控盲区问题。压缩包含2个…

2026/10/16 3:40:07 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →