我们可以来回移动流的指针以输出到文件吗?
Can we move the pointer of ofstream back and forth for output to file?
我需要将结果输出到具有预定义格式的文件中。这些列如下所示:
时间 COL1 COL2 COL3 COL4 ...
我正在使用流。我必须逐行输出结果。但是,某些列的结果可能在特定时间不可用。结果的顺序也可能不排序。
我可以在最初指定标题的同时控制列之间的间距。
我想我的问题是:是否可以每行水平来回移动流指针?
到目前为止我尝试的:1)使用以下方法查找流指针的当前位置:
long pos = fout.tellp()
2)根据间距计算要移动的位置:
spacing = column_spacing * column_number
long newpos = pos + spacing
3) 然后使用 seekp() 移动指针:
fout.seekp(newpos)
4)提供输出:
fout << "output"
这行不通。基本上,指针不会移动。这个想法是让 如果可能的话,让我的流 fout 来回移动。我将不胜感激任何关于如何控制它的建议。
有关输出的一些信息:我正在计算GPS卫星在天空中的仰角随时间的变化。因此,总共有 32 列与 GPS 卫星数量同义。在任何时间点,并非所有卫星都是可见的,因此需要跳过一些卫星/列。此外,由于观测文件的限制,卫星高程列表可能不会按升序排列。希望这有助于绘制情况。
所需输出的示例。标头(时间、SAT1、...SAT32)是在结果输出之前定义的,不是这里问题的一部分。每列之间的间距在定义标题期间控制(假设每列之间有 15 个空格)。输出可以截断为小数点后 1 位。写入当前时间 t 的所有结果后,将出现一个新行。然后我处理时间 t+1 的观测值,然后再次写入输出,依此类推。 因此,写作以划时代的方式发生。卫星高程存储在矢量(double)中,卫星编号存储在矢量(int)中。两个向量的长度相同。我只需要将它们写入文件。对于以下示例,时间的输出以秒为单位,卫星高程以度为单位:
TIME SAT1 SAT2 SAT3 ... SAT12 SAT13 ... SAT32
1 34.3 23.2 12.2 78.2
2 34.2 23.1 12.3 78.2
3 34.1 11.3 23.0 78.3
等等...您可能会注意到,卫星高程可能可用,也可能不可用,这完全取决于观测结果。我们还假设输出的大小和效率在这里不是优先事项。根据24小时的观察,输出文件大小可以达到5-10 MB。
提前感谢您的时间!
我们可以来回移动 ofstream 的指针以输出到文件吗?
不,您可能不想这样做(即使原则上可行;但这效率低下且代码非常脆弱,几乎不可能调试),特别是对于宽度可变的文本输出(我猜您的 COLi可以具有可变宽度,就像大多数文本格式中通常一样)。 看来你的方法错了。
一般的方法是在内存中构建输出文件的整个表示形式,作为"对象"或"数据结构"的图形。这通常就足够了,除非你真的需要输出一些巨大的东西。
如果您的典型文本输出具有合理的大小(最多几千兆字节),那么将数据表示为某种内部数据结构是值得的,这是非常普遍的做法。
如果你的文本输出很大(几十千兆字节或太字节,这真的不太可能),那么你将无法在内存中表示它(除非你有一台昂贵的计算机和一TB的RAM)。但是,您可以使用一些数据库(可能是 sqlite)作为内部表示形式。
在实践中,文本格式总是按顺序输出(来自某些内部表示),并且这些格式的文本文件具有合理的大小(因此今天拥有数 GB 的文本文件并不常见;在这种情况下,数据库 - 或在某些目录中将输出文件分成几部分 - 更好)。
如果没有精确指定您的文本格式(例如使用 EBNF 表示法)并给出示例 - 以及对输出大小的一些估计 - 您的问题太宽泛,您只能得到上述提示。
输出文件大小可以达到5-10 MB
这在当前的计算机上真的很小(即使是便宜的智能手机也有千兆字节的 RAM)。所以在内存中构建数据结构,完成后立即输出。
您应该使用什么数据结构取决于您的实际问题(以及程序获得的输入以及您希望它生成的精确输出)。由于您没有在问题中指定您的程序,因此我们无法提供帮助。可能C++标准容器和智能指针可能有用(但这只是一个猜测)。
你应该阅读一些编程的介绍(如SICP),然后阅读一些好的C++编程书籍,并阅读一些好的算法导论。你可能需要阅读一些关于编译技术的东西(因为它们包括解析和输出结构化数据),比如龙书。学习编程需要很多时间。
C++确实是一种非常困难的编程语言,我相信它不是学习编程的最佳方式。一旦你学会了如何编程,就把你的时间花在学习C++上。您的问题不在于std::ostream
或C++,而在于正确设计程序及其体系结构
顺便说一句,如果您的程序的输出正在馈送其他程序(并且不仅或主要供人类使用),您可能会使用一些已建立的文本格式,也许是JSON,YAML,CSV,XML(另请参阅此示例),....
2 34.2 23.1 12.3 78.2
上行中的空格有多重要(如果在第一个2
之后插入一个空格,而在12.3
之后删除另一个空格会发生什么)?像3.14159265358979323846264
这样的大量数字可以出现在您的输出中吗?或者你想要多少位数?这应该在某处精确记录!您是否可以改进上面的输出格式(您可能会使用一些符号,例如?
来表示丢失的数字;这将使输出不那么模糊,对人类来说更具可读性,并且更容易被其他程序解析)?
您需要精确地(用英语)定义程序的行为,包括其输入和输出格式。输入和输出的示例不是规范(它只是一个示例)。
顺便说一句,您可能还想对程序进行编码以提供几种不同的输出格式。例如,您可以决定提供CSV格式用于speadsheets,JSON格式用于其他数据处理,gnuplot输出以获得漂亮的数字,LaTeX输出以便能够在某些技术报告中插入您的输出,HTML输出可通过浏览器使用等。一旦您拥有计算数据的良好内部表示(作为方便的数据结构),以各种格式输出它就很容易且非常方便。
可能您的域(卫星处理)已经定义了一些广泛使用的数据格式。详细研究它们(至少是为了获得指定自己的输出格式的灵感)。 我根本不是卫星数据专家,但通过谷歌,我很快就找到了像澳大利亚地球科学这样的例子 (中新社)LANDSAT MATIC MAPPER 数字数据格式 描述(一百多页)。您应该像它们一样精确地指定输出格式(可能是几十页的英文,还有几页的 EBNF),而 EBNF 是一种方便的符号(有很多额外的英文解释)
还可以从其他输出数据格式描述中寻找灵感。
如果你发明了你的输出格式,你可能应该发布它的规范(英文),以便其他人可以编写程序,将你的输出作为他们代码的输入。
在许多领域,数据比处理数据的代码更有价值(即成本更高,以欧元或美元为单位)。这就是为什么应该精确记录其格式的原因。您需要指定该格式,以便 2030 年的未来程序员可以轻松地为其编写解析器。所以细节很重要。明确指定您的输出格式(在某些英文文档中)。
指定输出格式后,从一些足够好的内部数据表示中对输出例程进行编码很容易(并且不需要像移动输出的文件偏移量这样的疯狂技巧)。输出格式的足够好的规范也是设计内部数据表示的指南。
是否可以每行水平来回移动流指针?
这可能是可行的,但它效率低下且容易出错(并且无法调试),以至于在实践中您永远不应该这样做(而是详细指定您的输出并编写一个简单的顺序输出例程,就像所有文本格式相关软件一样)。
顺便说一句,今天我们在文本文件中到处都使用 UTF-8,单个 UTF-8 编码的 Unicode 字符可能跨越一个(例如,对于某些数字,如0
或拉丁字母,如E
)或几个字节(例如,对于重音字母,如é
,或西里尔字母,如я
,或符号,如∀
等),因此用另一个字符替换单个 UTF8 字符可能意味着一些字节插入或删除。
请注意,当前的文件系统不允许在文件中间插入字符或字节或删除字符范围(例如,在Linux 上,没有 syscalls(2) 允许这样做),并且并不真正了解行(行尾只是一个约定,例如n
Linux 上的字节)。这样做的程序(如您最喜欢的源代码编辑器)始终表示内存中的数据。今天,文件是一个字节序列,你只能在其末尾附加字节,或者在中间替换字节(从操作系统的角度来看);但是在文件中间插入或删除字节是不可能的,这就是为什么文本文件在实践中总是按顺序从头到尾写入,而不会在当前文件偏移量内移动(除了在其末尾附加字节)。
(如果这是某些CS学院或本科课程的家庭作业,我猜你的老师希望你定义和记录你的输出格式)
- 有没有办法简单地从 GPU 调用多个 cpp 输出文件?
- VI工作室代码错误无法打开输出文件主.exe
- 在代码块中查找输出文件
- 将未签名的字符写入输出文件
- 为什么我的代码不写入输出文件?
- 完成搜索任务时为空输出文件
- 如何将地图<列表<string>、矢量<string>>输出到输出文件?
- 无法在代码块 IDE 中打开输出文件.exe
- C++:更改 IF 语句中的输出文件
- 编译 gsoap 输出文件 (onvif) 时出现问题
- C++击球平均值程序使用输入/输出文件打印名称,平均值,最高/最低平均值时遇到麻烦
- while 循环中的流输出文件() 通常生成空文件
- 如何使用 Docker 访问输出文件
- 提升进程间共享内存删除、权限和输出文件
- 查找素数,然后将质数放入输出文件中
- GDB / C++ - 根据循环条件将多个变量记录到输出文件中
- 带有文件结束函数的 while 循环重复输出文件中的最后一个数字两次
- 我的输出文件未显示解决方案
- 输入文件中的第一个字符是输出文件中的最后一个字符,反之亦然
- C++,我正在尝试创建一个有效的.bmp输出文件