Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
C++文件位置控制 seekg tellg函数用法_创想鸟

C++文件位置控制 seekg tellg函数用法

seekg用于移动文件读取指针,tellg获取当前指针位置,二者结合可实现文件的随机访问。示例中先用tellg记录初始位置,读取一行后再次调用tellg获取新位置,随后用seekg跳回文件开头重新读取,再跳至文件末尾获取文件大小,最后跳转到指定偏移读取部分内容。处理大文件或二进制数据时需以binary模式打开文件,避免文本模式换行符转换导致的定位错误。常见陷阱包括越界访问和未检查流状态,正确使用可高效实现文件索引、跳转和解析。

c++文件位置控制 seekg tellg函数用法

C++中,

seekg

和

tellg

这两个函数是处理文件输入流(

ifstream

)时用于精确控制文件读取位置的关键工具。简单来说,

seekg

(seek get)负责移动文件读取指针到你指定的位置,而

tellg

(tell get)则告诉你当前读取指针在哪里。它们让你可以像在书本中翻页一样,跳到文件的任何一个地方开始阅读,或者知道自己读到了哪里。

解决方案

在使用C++处理文件时,特别是当你需要非顺序地读取文件内容,或者需要知道文件大小、当前读取进度时,

seekg

和

tellg

就显得尤为重要。它们通常与

ifstream

对象一起使用。

seekg()

函数允许你将输入流的“获取”或读取位置指针移动到指定位置。它有两个重载版本:

istream& seekg (streampos pos);

:将读取指针直接移动到文件中的绝对位置

pos

。

streampos

通常是

long long

或类似的类型,代表文件中的字节偏移量。

istream& seekg (streamoff off, ios_base::seekdir dir);

:将读取指针从

dir

(起始点)开始,偏移

off

个字节。

off

:一个

streamoff

类型的值,表示偏移量。可以是正数(向文件末尾移动)或负数(向文件开头移动)。

dir

:一个

ios_base::seekdir

枚举值,指定偏移的参照点:

ios_base::beg

:从文件开头开始偏移。

ios_base::cur

:从当前位置开始偏移。

ios_base::end

:从文件末尾开始偏移。

tellg()

函数则用于返回输入流的当前“获取”或读取位置。它返回一个

streampos

类型的值,代表从文件开头算起的当前字节偏移量。

立即学习“C++免费学习笔记(深入)”;

基本用法示例:

#include #include #include #include int main() {    std::ofstream ofs("example.txt");    ofs << "Hello World!" << std::endl;    ofs << "C++ File IO is cool." << std::endl;    ofs.close();    std::ifstream ifs("example.txt");    if (!ifs.is_open()) {        std::cerr << "无法打开文件!" << std::endl;        return 1;    }    // 1. 获取当前位置    std::streampos initialPos = ifs.tellg();    std::cout << "初始读取位置: " << initialPos << std::endl; // 通常是0    // 2. 读取一行    std::string line;    std::getline(ifs, line);    std::cout << "读取第一行: " << line << std::endl;    // 3. 再次获取当前位置    std::streampos afterFirstLinePos = ifs.tellg();    std::cout << "读取第一行后的位置: " << afterFirstLinePos << std::endl; // 会是"Hello World!n"的字节长度    // 4. 使用 seekg 移动到文件开头    ifs.seekg(0, std::ios::beg); // 等价于 ifs.seekg(initialPos);    std::streampos afterSeekBeg = ifs.tellg();    std::cout << "移动到文件开头后的位置: " << afterSeekBeg << std::endl;    // 5. 再次读取第一行,验证是否成功移动    std::getline(ifs, line);    std::cout << "再次读取第一行: " << line << std::endl;    // 6. 移动到文件末尾并获取文件大小    ifs.seekg(0, std::ios::end);    std::streampos fileSize = ifs.tellg();    std::cout << "文件大小: " << fileSize << " 字节" << std::endl;    // 7. 移动到文件中间某个位置    // 假设我们想从 "C++ File IO is cool." 的 "File" 开始读    // "Hello World!n" 大约13个字节,加上 "C++ " 4个字节,再加一个空格,就是18个字节    ifs.seekg(13 + 4 + 1, std::ios::beg); // 从开头偏移18个字节    std::cout << "移动到文件中间某个位置后的位置: " << ifs.tellg() << std::endl;    std::getline(ifs, line); // 这会从当前位置读到行尾    std::cout << "从中间读取: " << line << std::endl;    ifs.close();    // 清理文件    std::remove("example.txt");    return 0;}

为什么需要精确控制文件读取位置?

在我看来,文件读取位置的精确控制,是文件操作从“线性阅读”到“随机访问”的关键转变。试想一下,如果你有一本厚厚的字典,你不会从第一页开始一页一页地翻找一个词,而是会直接跳到对应的字母部分。文件操作也是如此。

很多时候,我们处理的文件并非简单文本,它们可能是:

大型数据库文件:你可能只需要读取某个特定记录,而不是把整个几GB甚至几十GB的文件加载到内存里。多媒体文件(如音频、视频):这些文件通常有复杂的内部结构,包含头部信息、元数据、以及实际的数据流。你可能需要跳过头部,直接定位到某个时间点的数据块。自定义二进制文件格式:例如,游戏存档文件、特定应用程序的数据文件。这些文件往往由固定大小或变长的数据块组成,每个块有特定的含义,你需要知道每个块的起始位置和大小,然后精确地跳过去读取。文件解析器或索引器:当你需要为文件内容建立索引时,你会在特定位置记录下某些数据的偏移量,以后就能直接通过这些偏移量快速定位。

没有

seekg

和

tellg

,我们只能顺序读取,这在处理大文件时效率极低,甚至是不可能的。它们为我们提供了一种“书签”和“跳转”的能力,让文件操作变得灵活而高效。

seekg

函数的参数解析与常见陷阱

seekg

的强大之处在于它的灵活性,但这种灵活性也带来了一些需要注意的细节,稍不留神就可能掉进“坑”里。

首先,再强调一下它的两个核心参数:

offset

(偏移量)和

dir

(参照点)。

offset

(偏移量):这个值可以是正数,表示向文件末尾方向移动;也可以是负数,表示向文件开头方向移动。它的类型是

streamoff

,这是一个有符号整数类型,通常足够大以处理大多数文件大小。

dir

(参照点):

std::ios::beg

:从文件开头算起。此时

offset

通常为非负数。例如,

seekg(100, std::ios::beg)

就是从文件开头跳过100个字节。

std::ios::cur

:从当前读取指针位置算起。

offset

可以是正数(向前)或负数(向后)。例如,

seekg(-50, std::ios::cur)

就是从当前位置回退50个字节。

std::ios::end

:从文件末尾算起。此时

offset

通常为负数,因为你要从末尾向前移动。例如,

seekg(-20, std::ios::end)

就是从文件末尾倒数20个字节的位置。

常见陷阱:

文本模式与二进制模式的差异:这是最容易犯错的地方!如果你以文本模式(默认模式)打开文件,

seekg

的行为可能会因为换行符的转换而变得不可预测。在Windows系统上,

n

(LF)在写入时可能被转换为

rn

(CRLF),在读取时又被转换回来。这意味着你

tellg

得到的位置可能不是实际的字节偏移量,

seekg

到某个位置也可能不准确。解决方案:处理二进制文件或需要精确字节定位时,务必使用

std::ios::binary

模式打开文件。例如:

std::ifstream ifs("data.bin", std::ios::binary);

。

越界操作:尝试将指针移动到文件开头之前(负偏移量超出文件开头)或文件末尾之后,可能会导致流进入错误状态(

failbit

或

badbit

被设置)。虽然有些系统可能允许你“寻求”到文件末尾之后(比如为将来写入预留空间),但对于读取操作,这通常意味着没有可读的数据。解决方案:在执行

seekg

后,总是检查流的状态,例如

if (!ifs.good()) { /* 处理错误 */ }

。

大文件处理:虽然

streamoff

通常足够大,但在极少数情况下,如果文件大小超过

streamoff

所能表示的最大值(例如,在32位系统上处理TB级文件),可能会出现问题。不过,现代C++标准库通常会确保

streamoff

和

streampos

足以处理操作系统支持的最大文件大小。解决方案:了解你所使用的系统和编译器对这些类型的实现,必要时考虑使用更底层的API(如Windows API的

SetFilePointerEx

或POSIX的

lseek64

),但这通常不是必需的。

tellg

返回值的限制:

tellg

返回的是

streampos

,它表示一个绝对位置。当你需要计算两个位置之间的字节数时,可以直接相减得到

streamoff

。

正确理解和规避这些陷阱,能让你在使用

seekg

时更加游刃有余。

tellg

与

seekg

结合使用的高级技巧

tellg

和

seekg

并非孤立存在的,它们常常是协同工作的“黄金搭档”,尤其在实现一些高级文件操作时。

获取文件大小:这是最常见的用法之一。通过将读取指针移动到文件末尾,然后用

tellg

获取其位置,你就能得到文件的总字节数。之后,别忘了把指针再移回文件开头,以便后续读取。

std::ifstream ifs("my_large_file.bin", std::ios::binary);if (!ifs.is_open()) { /* 错误处理 */ }ifs.seekg(0, std::ios::end); // 移动到文件末尾std::streampos fileSize = ifs.tellg(); // 获取当前位置,即文件大小ifs.seekg(0, std::ios::beg); // 移回文件开头,准备读取std::cout << "文件大小: " << fileSize << " 字节" << std::endl;

在我看来,这种方法比读取整个文件来计算大小要高效得多,特别是对于大文件。

“标记”与“返回”机制:在解析复杂文件格式时,你可能需要先读取一部分数据,然后根据这些数据决定跳到文件的另一个区域继续读取,最后再返回之前的位置。

tellg

可以帮你“记住”当前位置,而

seekg

则让你随时可以“跳回”。

// 假设你正在解析一个自定义格式文件std::ifstream ifs("complex_data.dat", std::ios::binary);// ... 读取一些头部信息 ...// 假设头部信息告诉你,真正的数据块在文件某个特定偏移量处// 但你可能需要先处理一个中间的索引区std::streampos bookmark = ifs.tellg(); // 记住当前位置// 跳到索引区处理ifs.seekg(index_offset, std::ios::beg);// ... 读取并处理索引数据 ...// 处理完索引后,跳回之前标记的位置继续读取主数据ifs.seekg(bookmark);// ... 继续读取主数据 ...

这种模式在处理嵌套结构或交叉引用数据的文件时特别有用。

相对偏移与精确跳转:当你需要从当前位置精确地向前或向后跳跃特定字节数时,

seekg

结合

std::ios::cur

非常方便。

// 假设你当前在文件中的某个位置// 想跳过接下来的N个字节long long bytesToSkip = 1024;ifs.seekg(bytesToSkip, std::ios::cur); // 从当前位置向前跳1024字节

或者,你也可以先

tellg

获取当前位置,然后直接用

seekg(current_pos + offset)

来实现绝对跳转。

std::streampos currentPos = ifs.tellg();long long relativeOffset = 50; // 相对当前位置向前50字节ifs.seekg(currentPos + relativeOffset);

我个人更倾向于后一种方式,因为它在逻辑上更清晰,特别是当涉及到复杂的偏移计算时。

streampos

和

streamoff

的算术运算是定义好的,可以放心地进行加减。

理解这些高级用法,能够让你在处理文件时拥有更强大的控制力,构建出更健壮、更高效的文件处理程序。它们是C++文件I/O的基石,值得花时间深入掌握。

以上就是C++文件位置控制 seekg tellg函数用法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1472705.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
C++数据结构布局 缓存行友好设计
上一篇 2025年12月18日 19:50:14
C++栈内存管理 局部变量分配原理
下一篇 2025年12月18日 19:50:35

相关推荐

  • 360浏览器怎么禁止网页自动刷新_360浏览器阻止页面定时刷新设置方法

    1、通过360浏览器开发者工具删除含http-equiv=”refresh”的meta标签可临时阻止刷新;2、启用弹窗拦截功能可屏蔽由脚本触发的自动刷新;3、使用无痕模式浏览可限制脚本运行,避免页面刷新;4、安装“Tampermonkey”等扩展并添加屏蔽规则可实现长期有效阻…

    2026年9月22日
    200
  • windows怎么关闭操作中心通知_禁用系统和应用通知消息教程

    关闭Windows通知可提升专注度,首先通过“设置-系统-通知”关闭所有通知或按需保留;其次启用“专注助手”在特定场景屏蔽干扰;再通过任务栏设置隐藏操作中心图标;专业版用户可通过组策略禁用操作中心;家庭版可修改注册表HKEY_CURRENT_USERSoftwarePoliciesMicrosoft…

    2026年9月22日
    100
  • 在Java中如何通过Stream实现交集与差集

    交集可通过filter结合contains获取两集合共有元素,差集则保留一个集合中不在另一集合的元素,示例使用list1.stream().filter(list2::contains)得[3,4],filter(e->!list2.contains(e))得[1,2],建议将list2转为H…

    2026年9月22日
    000
  • Java Swing中按钮与文本框事件处理的实践指南

    本文将深入探讨Java Swing中ActionListener的正确使用方法,指导开发者如何为GUI按钮和文本框实现事件监听,从而处理用户输入、执行计算并实时更新界面。文章将重点讲解如何在actionPerformed方法中获取用户输入、进行类型转换、处理潜在异常,并提供一个完整的计算器示例来演示…

    2026年9月22日
    100
  • MySQL查询缓存配置及性能_MySQL重复查询响应速度提升

    MySQL查询缓存配置及性能_MySQL重复查询响应速度提升MySQL查询缓存配置及性能_MySQL重复查询响应速度提升MySQL查询缓存配置及性能_MySQL重复查询响应速度提升MySQL查询缓存配置及性能_MySQL重复查询响应速度提升

    mysql查询缓存已不适用于现代应用场景,尤其在8.0版本中被彻底移除。它仅适合读多写少、数据几乎不变的静态查询,通过内存直接返回结果提升性能;但在数据频繁更新时,因基于表级的缓存失效机制,每次写操作都会清空相关缓存,导致频繁重建缓存并消耗大量cpu资源,形成性能瓶颈。此外,sql语句匹配严格、内存…

    2026年9月22日 • 用户投稿
    400
  • VSCode搭建前端开发环境(新手必备,插件配置详解)

    vscode是前端开发的理想选择,因其轻量、可扩展且拥有活跃的社区支持,能通过插件将基础编辑器打造成高效智能的开发环境。其优势在于启动快、资源占用低、内置git和调试工具,并拥有强大的插件生态,适配react、vue等各类前端技术栈。新手必装插件包括eslint与prettier(保障代码规范与格式…

    2026年9月22日
    000
  • Linux平台下的Eclipse配置

    在linux平台上配置eclipse时,可能会遇到一些常见的问题和优化需求。本文将详细介绍如何解决这些问题,并提供优化eclipse的建议。 启动Eclipse报错 启动Eclipse时,如果遇到以下错误: A Java Runtime Environment (JRE) or Java Devel…

    2026年9月22日
    000
  • 怎样在iPhone情侣模式中分享视频?快速上传和同步的实用方法

    怎样在iPhone情侣模式中分享视频?快速上传和同步的实用方法怎样在iPhone情侣模式中分享视频?快速上传和同步的实用方法怎样在iPhone情侣模式中分享视频?快速上传和同步的实用方法怎样在iPhone情侣模式中分享视频?快速上传和同步的实用方法

    最实用的方法是使用iCloud共享相簿,它支持情侣间视频快速上传与实时同步。首先双方需开启iCloud照片中的共享相簿功能,然后创建专属相簿并邀请对方加入。此后,任一方添加的视频会自动同步至对方设备,且不占用个人iCloud空间。相比AirDrop(限近距离)、即时通讯工具(压缩画质)或云盘(占存储…

    2026年9月22日 • 用户投稿
    000
  • 想靠抖音带货赚钱?教你一键挂小黄车教程

    想靠抖音带货赚钱?教你一键挂小黄车教程想靠抖音带货赚钱?教你一键挂小黄车教程想靠抖音带货赚钱?教你一键挂小黄车教程想靠抖音带货赚钱?教你一键挂小黄车教程

    想靠抖音带货赚钱并不复杂,关键在于掌握正确方法。一、开通商品橱窗权限:需实名认证并发布原创视频,确保账号无违规记录;二、视频挂载小黄车:发布视频时点击“添加商品”按钮,选择商品并设置展示位置与时间;三、选品提升转化率:贴合视频内容、关注价格销量、参考热榜商品并测试不同组合;四、直播挂小黄车:互动性强…

    2026年9月22日 • 用户投稿
    100
  • 如何判断网络延迟(Ping值)过高是由运营商问题还是自身设备引起的?

    先重启设备并检查本地连接,若有线网络延迟降低则问题在无线信号;通过ping网关和外部DNS判断故障范围,结合tracert追踪路径,前几跳异常指向运营商问题,最后用官方测速工具验证并联系客服解决。 判断网络延迟高是运营商还是自身设备的问题,关键在于逐步隔离排查。从最接近你的设备开始测试,向外层层推进…

    2026年9月22日
    100
  • VSCode如何实现代码混淆 VSCode保护源代码的加密方案

    代码混淆无法通过vscode直接实现,需借助外部工具或构建流程。1. 使用构建工具如webpack或rollup配合terser等混淆器,在打包时自动混淆代码,通过vscode配置tasks.json运行构建任务。2. 可选vscode插件辅助,但应评估其安全性、混淆强度、性能影响、配置灵活性及社区…

    2026年9月22日
    100
  • 运营蝴蝶号必懂的五大策略,帮你迅速提升粉丝活跃度

    运营蝴蝶号必懂的五大策略,帮你迅速提升粉丝活跃度运营蝴蝶号必懂的五大策略,帮你迅速提升粉丝活跃度运营蝴蝶号必懂的五大策略,帮你迅速提升粉丝活跃度运营蝴蝶号必懂的五大策略,帮你迅速提升粉丝活跃度

    要真正提升“蝴蝶号”粉丝活跃度,核心在于建立深层次连接与持续价值输出。1.内容需有“钩子”,引发粉丝思考和表达欲;2.互动要升级为共创场景,如提问、投票、征集等方式增强参与感;3.构建专属社群(如微信群、discord)强化归属感;4.利用数据分析找准内容方向与粉丝活跃时段;5.跳出单平台思维,进行…

    2026年9月22日 • 用户投稿
    100
  • AdobeIllustrator如何导出AI生成的图片?矢量图像保存的步骤

    首先明确输出需求,再选择“文件>导出>导出为…”或“文件>存储为…”,根据用途选取合适格式如SVG、PDF或AI,确保矢量信息保留,参数设置需匹配目标平台要求。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ Adob…

    2026年9月22日
    000
  • PHP面向对象开发:解决父类构造器参数在嵌套子对象方法中丢失的问题

    在PHP面向对象编程中,我们经常会遇到类继承和对象组合的场景。一个常见的问题是,当父类构造函数接收参数并用于初始化内部的子对象时,该子对象的方法在后续调用中可能无法正确访问到这些参数,甚至显示为null。本文将深入探讨这一问题,并提供两种有效的解决方案。 引言与问题阐述 考虑一个典型的web应用架构…

    2026年9月22日
    000
  • 使用MockWebServer对FeignClient进行单元测试

    本文详细阐述了如何利用Spring Cloud LoadBalancer和MockWebServer对FeignClient进行高效单元测试。通过在测试配置中动态注册MockWebServer实例,并将其作为FeignClient的服务发现目标,开发者可以精确模拟后端API的行为,包括各种HTTP响…

    2026年9月22日
    000
  • Sublime快速定位MySQL死锁与阻塞问题_提高系统稳定性与并发处理能力

    Sublime快速定位MySQL死锁与阻塞问题_提高系统稳定性与并发处理能力Sublime快速定位MySQL死锁与阻塞问题_提高系统稳定性与并发处理能力Sublime快速定位MySQL死锁与阻塞问题_提高系统稳定性与并发处理能力Sublime快速定位MySQL死锁与阻塞问题_提高系统稳定性与并发处理能力

    mysql死锁和阻塞问题可通过sublime分析日志排查。1.使用关键词搜索及正则匹配快速定位死锁信息块;2.通过查找waiting状态事务并折叠无关内容聚焦阻塞链;3.结合general log与事务id查找sql执行顺序;4.利用语法高亮、列选择等功能提升日志可读性。这些方法能有效提高排查效率。…

    2026年9月22日 • 用户投稿
    100
  • 常见分布式任务调度工具浅析

    一、背景 在日常业务中,经常会遇到需要在特定时间执行任务或周期性执行任务的需求。这些任务通常被归类为定时任务。为了满足这种需求,各种任务调度框架应运而生,如Timer、ScheduledThreadPoolExecutor(没错,它也可以用于定时任务)、Quartz等。然而,随着分布式和微服务的发展…

    2026年9月22日
    100
  • win11平板模式无法自动切换怎么办_win11平板模式自动切换异常修复方法

    首先检查设备形态和设置,确保键盘分离或屏幕翻转到位,并在“平板电脑”设置中启用自动切换;若无效,重启Windows资源管理器、更新传感器驱动或重装感应式旋转锁驱动;最后通过sfc /scannow命令修复系统文件,恢复平板模式自动切换功能。 如果您发现Windows 11的平板模式无法根据设备形态自…

    2026年9月22日
    100
  • Canva中AI生成图片如何导出?教你快速保存设计作品的方法

    答案:Canva中导出AI生成图片的操作与普通图片相同,点击右上角“分享”按钮,选择“下载”,可选PNG、JPG、PDF、SVG、MP4或GIF等格式;为保证画质,建议优先选用PNG格式,避免有损压缩,同时选择高分辨率和合适尺寸,Pro用户可进一步调整质量与透明背景设置;除下载外,还可通过分享链接、…

    2026年9月22日
    800
  • windows怎么用命令行删除顽固文件_命令行删除顽固文件的方法

    使用命令行可强制删除顽固文件,先以管理员身份运行cmd或PowerShell,通过del /f /q或Remove-Item -Force命令删除文件,若被占用则用taskkill终止进程,或进入安全模式删除,也可用rd /s /q删除整个目录。 如果您尝试删除某个文件时,发现资源管理器无法完成操作…

    2026年9月22日
    200

发表回复

登录后才能评论
关注微信