我一直在尝试阅读 iostreams 并更好地理解它们。有时我发现它强调插入器( << )和提取器( >> )旨在用于文本序列化。这是几个地方,但这篇文章是一个很好的例子:
http://spec.winprog.org/streams/
外<iostream>在某些情况下,< 和="">> 以类似流的方式使用,但不遵守任何文本约定。例如,当 Qt 的 QDataStream 使用时,它们会写入二进制编码的数据。 :
http://doc.qt.nokia.com/latest/qdatastream.html#details
在语言级别,< 和="">> 运算符属于您的项目要重载(因此 QDataStream 所做的显然是可以接受的)。我的问题是对于那些使用 <iostream> 的人来说,这是否被认为是一种不好的做法。使用 < 和="">> 运算符来实现二进制编码和解码。 (例如)是否有任何期望,如果写入磁盘上的文件,该文件应该可以使用文本编辑器查看和编辑?
是否应该始终使用其他方法名称并基于 read()和 write() ?或者应该将文本编码仅仅视为与标准库 iostream 集成的类可以选择忽略的默认行为?
更新 关于此的一个关键术语问题似乎是“格式化”与“未格式化”的 I/O 的区别(与术语“文本”与“二进制”相反)。我发现了这个问题:
writing binary data (std::string) to an std::ofstream?
它有来自@TomalakGeret'kal 的评论说:“无论如何,我不想将 <>
该问题的公认答案说,只要您使用 ios::binary 就可以了.这似乎支持了辩论中“没有任何问题”的一面……但我仍然没有看到关于这个问题的任何权威来源。
最佳答案
其实运营商<<和 >>是位移运算符;将它们用于 I/O 严格来说已经是一种误用。然而,这种误用与运算符重载本身一样古老,而今天的 I/O 是它们最常见的用法,因此它们被广泛认为是 I/O 插入/提取运算符。我很确定如果没有 iostreams 的先例,没有人会使用这些运算符进行 I/O(尤其是在 C++11 中,它具有可变参数模板,解决了使用这些运算符为 iostreams 解决的主要问题,在一个更清洁的方式)。另一方面,从语言的角度来看,重载operator<<和 operator>>可以表示任何您希望他们表示的意思。
所以问题归结为这些运算符的可接受用途是什么。为此,我认为必须区分两种情况:第一,在 iostream 类上工作的新重载,第二,在其他类上工作的新重载,可能被设计为像 iostreams 一样工作。
让我们首先考虑 iostream 类上的新运算符。让我首先观察到 iostream 类都是关于格式化的(以及相反的过程,可以称为“解格式”;“词法分析”在这里不太合适,因为提取器不能确定类型,但只能尝试根据给定的类型解释数据)。负责原始数据的实际 I/O 的类是流缓冲。但是请注意,正确的二进制文件不是您只转储内部原始数据的文件。就像一个文本文件(实际上更是如此),一个二进制文件应该对它所包含的数据有一个明确指定的编码。特别是如果文件需要在不同的系统上读取。因此,格式化输出的概念对于二进制文件也非常有意义;只是格式不同(例如,为整数值写入预定数量的字节,最重要的字节在前)。
iostreams 本身是用于处理文本文件的类,也就是说,处理其内容被解释为数据的文本表示的文件。许多内置行为都为此进行了优化,如果在二进制文件上使用可能会导致问题。一个明显的例子是默认情况下在尝试任何输入之前跳过空格。对于二进制文件,这显然是错误的行为。此外,语言环境的使用对二进制文件没有意义(尽管有人可能会争辩说可能存在“二进制语言环境”,但我不认为为 iostream 定义的语言环境为此提供了合适的接口(interface))。因此我会说写二进制 operator<<或 operator>>对于 iostream 类将是错误的。
另一种情况是为二进制输入/输出定义一个单独的类(可能重用流缓冲层来执行实际的 I/O)。由于我们现在谈论的是不同的类,因此上面的论证不再适用。所以现在的问题是:应该operator<<和 operator>>在 I/O 上被视为“文本插入/提取操作符”或更一般地被视为“格式化数据插入/提取操作符”?标准类仅将它们用于文本,但是,根本没有用于二进制 I/O 插入/提取的标准类,因此标准用法无法区分两者。
我个人会说二进制插入/提取与文本插入/提取足够接近,这种用法是合理的。请注意,您还可以制作有意义的二进制 I/O 操纵器,例如bigendian , littleendian和 intwidth(n)确定要输出的整数的格式。
除此之外,还可以将这些运算符用于不是真正 I/O 的事情(并且您甚至不会想到使用 streambuf 层),例如从容器中读取或插入到容器中。在我看来,这已经构成了对运营商的滥用,因为那里的数据没有转换成或转换成不同的格式。它只是存储在一个容器中。
关于c++ - 插入器和提取器读取/写入二进制数据与文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8230786/
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
我正在使用Ruby,我正在与一个网络端点通信,该端点在发送消息本身之前需要格式化“header”。header中的第一个字段必须是消息长度,它被定义为网络字节顺序中的2二进制字节消息长度。比如我的消息长度是1024。如何将1024表示为二进制双字节? 最佳答案 Ruby(以及Perl和Python等)中字节整理的标准工具是pack和unpack。ruby的packisinArray.您的长度应该是两个字节长,并且按网络字节顺序排列,这听起来像是n格式说明符的工作:n|Integer|16-bitunsigned,network(bi
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是: