打印二进制数据? [英] printing binary data?

查看:95
本文介绍了打印二进制数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写像hexel这样的程序。我想我可以找出hexel的

来源,看看那个,但是现在我想弄清楚用std我可以做什么

: :stringstream和std :: string。我有一些

使用std :: string。我只是将它视为一个STL容器,并且在它的元素上迭代了
。结果对我来说有点混乱。一些

的东西打印出1或2个字符的十六进制数字,因为我希望
。其他字符打印出来的东西看起来像是b $ b代表比一个字节更大的数据大小。例如:


00 04 00 fffffff1 ffffffff


我决定尝试获取std :: string :: data()表示,并且然后

使用常规的char指针,但这并不像我天真的预期那样工作。

例如,我试图将字符串的大小添加到指针

从std :: string :: data返回;结果是0;


使用原始数据字节比使用

字符串有更好的方法吗?我的意思是使用标准库中的工具?


我在想我的问题是因为语言环境设置为

en_US.UTF -8,但我真的不知道这会怎样影响

std :: string的行为;


-

如果我们的假设是关于任何事情而不是关于某一个或多个特定事物,那么我们的推论就构成了数学。因此,数学可能被定义为我们永远不知道我们所讨论的是什么,以及我们所说的是否属实的主题.- Bertrand Russell

解决方案

Steven T. Hatton写道:

我正在尝试编写像hexel这样的程序。我想我可以找出hexel的源代码并查看它,但是现在我想弄清楚如何用std :: stringstream和std :: string来处理它。我有一些
使用std :: string。我只是将它视为STL容器,并对其元素进行迭代。结果对我来说有点混乱。有些东西打印出1或2个字符的十六进制数字,正如我预期的那样。其他字符打印出来的东西看起来像是代表一个比字节更大的数据大小。例如:

00 04 00 fffffff1 ffffffff

我决定尝试获取std :: string :: data()表示,然后
使用常规char指针,但这并不像我天真的预期那样工作。
例如,我试图将字符串的大小添加到从std :: string :: data返回的指针
;结果是0;

使用原始数据字节比使用
字符串有更好的方法吗?我的意思是使用标准库中的工具?

我在想我的问题是因为语言环境设置为
en_US.UTF-8,但我真的不喜欢不知道这可能会如何影响
std :: string的行为;




确保你的数据是无符号的(领先的''f''是符号扩展)。

另外,如果你需要,只在你的输出中用0xff掩盖它。


ie:而不是


os<< * p;


使用:


os<< (* p& 0xff); //最糟糕的情况


>>其他字符在我看来是

代表比一个字节更大的数据大小。例如:

00 04 00 fffffff1 ffffffff



一个纯粹的猜测:字符正在转换为签名的整数,即

您的8位十六进制值的来源。

使用原始数据字节比使用
字符串更好吗?我的意思是使用标准库中的工具?




我们不知道你做了什么,因为有_NO_示例代码

或者一个例子是什么你想要的数据输出。


Stephen Howe


" Stephen Howe" < sjhoweATdialDOTpipexDOTcom>写道:

其他字符打印出来的东西在我看来是代表一个更大的数据大小超过一个字节。例如:

00 04 00 fffffff1 ffffffff
一个纯粹的猜测:字符正在转换为有符号的int,这是8位十六进制值的来源。


这是我的假设。问题似乎是std :: string和
std :: ifstream等正在使用signed char;这是C ++标准中令人烦恼的一个方面之一。


我使用std :: ifstream读取数据,然后我使用了std :: ostringstrm将

转换为std :: string。

使用原始数据字节比使用
字符串有更好的方法吗?我的意思是使用标准库中的工具?



我们不知道你做了什么,因为有_NO_示例代码
或者你需要什么数据输出的例子。




我认为我很清楚我想要每个数据单元的两个字符hex

表示。我问是否有标准库的

组件更适合处理

二进制形式的数据。也许类似于Java的'

java.io.ByteArrayInputStream:

http://java.sun.com/j2se/1.5.0/docs/...putStream.html


这个东西很适合:
http://java.sun.com/j2se/1.5.0/docs/...ocketImpl.html
http://java.sun.com/j2se/1.5.0/docs/...verSocket.html

具有讽刺意味的是,其中一个主要的设计特色是让它如此可行是从TC ++ PL获取的指示。甚至命名惯例也是Stroustrup引入的一个b
。对于C ++产品,我经常发现自己花费更多的时间来尝试第二次猜测宏并理解特定实现的特殊性b / b
。很遗憾很少有C ++程序员

真正理解我在说什么。 C ++本身并没有那么多的错误。这些问题是由于人们无法理解多大的问题导致的大问题。


我根据280行程序启动了下面列出的代码使用了所有

种典型的C风格卷积。还有一小部分

原始功能缺失,但我可以使用大约五行

代码进行恢复。我想出的负值char值的解决方案非常明显。我现在明白,8位十六进制值是

将负字符转换为unsigned int的结果。转换为int是必要的

因为实现尝试将char数据打印为字符,而

它将int打印为数字。


#include< iostream>

#include< fstream>

#include< iomanip>

#include< sstream>

#include< string>

namespace hexlite {

using namespace std;

typedef string :: const_iterator c_itr;


ostream& printline(c_itr start,c_itr stop,ostream& out){

while(start< stop)out<< setw(2)<<(128 + static_cast< int>(* start ++) )<<" " ;;

退出;

}


ostream& dump(const string& dataString,ostream& out){


ostream hexout(out.rdbuf());

hexout.setf(ios :: hex ,ios :: basefield);

hexout.fill(''0'');


c_itr来自(dataString.begin());

c_itr dataEnd(来自+ dataString.size());

c_itr end(dataEnd - (dataString.size()%16));

(b_itr start = from; start< end; start + = 16)
printline(start,start + 16,hexout)<< endl;


printline(end,dataEnd,hexout)<< endl;

退出;

}

}


int main(int argc,char * argv []){

if(argc< 1){std :: cerr<<""输入文件名<<< std :: endl;返回-1; }


std :: ifstream inf(argv [1]);

if(inf){

std :: ostringstream oss;

oss<< inf.rdbuf();

hexlite :: dump(oss.str(),std :: cout);

返回0;

}

std :: cerr<<" \ n无法打开文件:"<< argv [1]<< std :: endl;

返回-1;

}

-

如果我们的假设是关于任何事情而不是关于某一个或多个

特定的东西,然后我们的推论构成数学。因此,数学可能被定义为我们永远不知道我们所讨论的是什么,以及我们所说的是否属实的主题.- Bertrand Russell


I''m trying to write a program like hexel. I guess I could fish out the
source for hexel and look at that, but for now I''m trying to figure out how
I can do with with std::stringstream and std::string. I had something
working with std::string. I simply treated it as an STL container, and
iterated over its elements. The results were a bit confusing to me. Some
of the stuff was printing out as 1 or 2 characters hex numbers, as I
expected. Other characters were printing out in what looks to me to be
representative of a larger data size than a byte. For example:

00 04 00 fffffff1 ffffffff

I decided to try fetching the std::string::data() representation, and then
to use regular char pointers, but that didn''t work as I naively expected.
For example, I was trying to add the size of the string to the pointer
returned from std::string::data; The result was 0;

Is there a better approach to working with bytes of raw data than using
strings? I mean using tools from the Standard Library?

I''m thinking my problem is comming from the fact that the locale is set to
en_US.UTF-8, but I really don''t know how that might impact the behavior of
std::string;

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell

解决方案

Steven T. Hatton wrote:

I''m trying to write a program like hexel. I guess I could fish out the
source for hexel and look at that, but for now I''m trying to figure out how
I can do with with std::stringstream and std::string. I had something
working with std::string. I simply treated it as an STL container, and
iterated over its elements. The results were a bit confusing to me. Some
of the stuff was printing out as 1 or 2 characters hex numbers, as I
expected. Other characters were printing out in what looks to me to be
representative of a larger data size than a byte. For example:

00 04 00 fffffff1 ffffffff

I decided to try fetching the std::string::data() representation, and then
to use regular char pointers, but that didn''t work as I naively expected.
For example, I was trying to add the size of the string to the pointer
returned from std::string::data; The result was 0;

Is there a better approach to working with bytes of raw data than using
strings? I mean using tools from the Standard Library?

I''m thinking my problem is comming from the fact that the locale is set to
en_US.UTF-8, but I really don''t know how that might impact the behavior of
std::string;



Make sure your data is unsigned (the leading ''f''s are sign extension).
Also, if you need to, mask it with 0xff just in your output.

i.e.: instead of

os << *p;

use:

os << (*p & 0xff); // worst case scenario


>> Other characters were printing out in what looks to me to be

representative of a larger data size than a byte. For example:

00 04 00 fffffff1 ffffffff


A pure guess: characters are being converted signed ints and that is the
source of your 8-digit hex values.
Is there a better approach to working with bytes of raw data than using
strings? I mean using tools from the Standard Library?



We have no idea what you did as there is _NO_ example code
or an example what data output you wanted.

Stephen Howe


"Stephen Howe" <sjhoweATdialDOTpipexDOTcom> wrote:

Other characters were printing out in what looks to me to be
representative of a larger data size than a byte. For example:

00 04 00 fffffff1 ffffffff
A pure guess: characters are being converted signed ints and that is the
source of your 8-digit hex values.
That was my supposition. The problem seems to be that std::string and
std::ifstream, etc., are using signed char; which is one of the more
annoying aspects of the C++ Standard.

I read the data using std::ifstream, then I used a std::ostringstrm to
convert it to std::string.
Is there a better approach to working with bytes of raw data than using
strings? I mean using tools from the Standard Library?


We have no idea what you did as there is _NO_ example code
or an example what data output you wanted.



I thought it was fairly clear that I wanted two character hex
representations of each unit of data. I was asking if there were
components of the Standard Library better suited to working with data in
binary form. Perhaps something similar to Java''s
java.io.ByteArrayInputStream:

http://java.sun.com/j2se/1.5.0/docs/...putStream.html

This stuff''s pretty nice to work with:
http://java.sun.com/j2se/1.5.0/docs/...ocketImpl.html
http://java.sun.com/j2se/1.5.0/docs/...verSocket.html

Ironically, one of the primary design features which makes it so viable is
taken direction from TC++PL. Even the naming convention is the one
Stroustrup introduced. Whith C++ products, I often find myself spending
more time trying to second guess macros and understand the idiosyncracies
of the particular implementation. It''s a shame so few C++ programmers
really understand what I''m talking about. There''s really not that much
wrong with C++, per se. The problems result from people failing to
understand how little things add up to big problems.

I started the code listed below based on a 280 line program that used all
kinds of typical C-style convolutions. There is a small bit of the
original functionality missing, but I can restor that with about five lines
of code. The solution I came up with for the negative char values is quite
obvious. I now understand that the 8-place hex values are the result of
converting a negative char to an unsigned int. Casting to int is necessary
because the implementation tries to print char data as characters, whereas
it prints ints as numbers.

#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>

namespace hexlite {
using namespace std;
typedef string::const_iterator c_itr;

ostream& printline(c_itr start, c_itr stop, ostream& out) {
while(start<stop) out<<setw(2)<<(128 + static_cast<int>(*start++))<<" ";
return out;
}

ostream& dump(const string& dataString, ostream& out) {

ostream hexout(out.rdbuf());
hexout.setf(ios::hex, ios::basefield);
hexout.fill(''0'');

c_itr from (dataString.begin());
c_itr dataEnd (from + dataString.size());
c_itr end (dataEnd - (dataString.size()%16));

for(c_itr start = from; start < end; start += 16)
printline(start, start + 16, hexout)<<endl;

printline(end, dataEnd, hexout)<<endl;
return out;
}
}

int main(int argc, char* argv[]) {
if (argc < 1) { std::cerr<<"enter a file name"<<std::endl; return -1; }

std::ifstream inf(argv[1]);
if(inf) {
std::ostringstream oss;
oss << inf.rdbuf();
hexlite::dump(oss.str(), std::cout);
return 0;
}
std::cerr <<"\nCan''t open file:"<<argv[1]<<std::endl;
return -1;
}
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell


这篇关于打印二进制数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆