c++如何解析Subtitle Edit生成的SRT字幕文件【实战】

夏萱大大_3383

夏萱大大_3383

2026-04-10

537人浏览

原创

srt文件应按块切分而非逐行读:缓存非空行至遇空行即得一完整字幕块;时间码用find_first_of定位分隔符后分段转换,异常则标记无效;序号不可靠,应存入vector并按时间排序;utf-8字幕解析无需解码,输出乱码需设控制台编码为cp_utf8。

c++如何解析subtitle edit生成的srt字幕文件【实战】

怎么读取SRT文件的结构而不被序号和空行搞乱

SRT 文件本质是纯文本,但格式松散:序号、时间码、多行字幕、空行交替出现。直接用 std::getline 逐行读容易在空行处断错,或把第二行时间当成字幕内容。关键不是“解析”,而是“按块切分”——每个字幕块以非空行开头,以连续空行结束。

实操建议:

  • 用 std::string 缓存当前块,每次读一行,遇到空行且缓存非空时,就完成一个块的提取
  • 跳过首尾空白(std::isspace),避免因 Windows/Linux 换行符差异误判空行
  • 序号行必须是纯数字(可选带空格),别用 std::stoi 直接转——万一有乱码会抛异常,先用 std::all_of 校验字符

时间码字符串怎么安全转成毫秒整数

SRT 时间码形如 00:01:23,456,逗号分隔毫秒,但有些老工具(包括某些 Subtitle Edit 版本)可能输出句点 . 或漏前导零。硬写 sscanf 容易崩,比如 0:5:7,89 这种不规范格式。

实操建议:

  • 用 std::string::find_first_of(",:.") 定位分隔符位置,分三段切:冒号前是小时,两个冒号间是分钟,第二个冒号到分隔符间是秒,分隔符后是毫秒
  • 每段用 std::stoi 转,捕获 std::invalid_argument 和 std::out_of_range 异常,出错则该条字幕标记为无效,不中止整个解析
  • 毫秒字段不足3位(如 12)要补零再转,避免当成12毫秒而非120毫秒

为什么用 std::vector<subtitleentry></subtitleentry> 而不用 std::map<int ...></int>

有人想用序号当 key 存进 std::map,但 Subtitle Edit 导出的 SRT 序号未必连续(比如删过某条后重新编号,中间留空),甚至可能重复(手动编辑导致)。更麻烦的是,播放器实际依赖时间轴,不是序号。

C++ 算法竞赛自动化测试数据生成与校验框架
C++ 算法竞赛自动化测试数据生成与校验框架

根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。

下载

实操建议:

  • 定义结构体 SubtitleEntry,至少含 start_ms、end_ms、text(std::string)三个字段
  • 全部存进 std::vector,后续按需排序(用 std::sort + lambda 比较 start_ms)
  • 如果要做二分查找(比如根据播放时间找当前字幕),排序后用 std::lower_bound,别自己写循环

处理中文等 UTF-8 字幕时,Windows 控制台直接 std::cout 是乱码

Subtitle Edit 默认保存为 UTF-8(无 BOM),但 VS 的控制台默认是 GBK,std::cout 会把 UTF-8 字节流当 GBK 解码,显示为乱码。这不是解析错了,是输出层问题。

实操建议:

  • 解析阶段完全不用管编码——UTF-8 是字节序列,std::string 照存即可
  • 若需调试输出,在 Windows 上用 SetConsoleOutputCP(CP_UTF8)(需 <windows.h></windows.h>),并在程序开头调用一次
  • 更稳妥的做法:调试时把 text 写入 UTF-8 文件(用 std::ofstream + .open(..., std::ios::binary)),用记事本或 VS Code 查看

真正难的不是读出字段,而是接受 SRT 本身没有标准——Subtitle Edit 可能导出带 HTML 标签的 <i>斜体</i>,也可能把换行写成 \n 或 <br>。解析器得明确目标:只取纯文本?还是保留简单格式?前者删标签就行,后者就得加个微型 HTML 解析器。这个边界不划清,后面永远在修 case。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

5219

3

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

2023.09.04

1098

7

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1558

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2244

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

5764

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

4849

6

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

2024.03.22

6574

16

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2024.04.29

8834

11

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.07.29

4479

17

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习