Re: How to read/write continuous hex dump using STL
<capnwhit@yahoo.com> wrote in message
news:1183228262.200756.260440@n2g2000hse.googlegroups.com...
On Jun 30, 12:32 pm, "Mike Wahler" <mkwah...@mkwahler.net> wrote:
The '>>' operator stops reading upon encountering whitespace.
So it tried to read hex value '6162636465', which is
418262508645 in decimal, most likely outside the guaranteed range
of type 'int' for your platform (32 bits?).
This post is for the benefit of the archive and anybody who reads
this thread in the future. I believe Mike recompiled the program
and used "abcde" as input, instead of "abcd". That is the reason
why he says that the program tried to read hex value '6162636465'.
Actually, I compiled if almost it as you posted it, but with the addition
of #include <cassert>, and the check of 'iss' stream state.
The original program tries to read hex value '61626364' which is
32 bits.
Actually, my error was that I simply typed the
(wrong) hex value into a calculator and converted to decimal.
I just now made a few more modifications to the code to 'watch' it and
realized:
The real reason for the fail state of 'iss' was that the entire
hex value (0x61626364) was read into 'temp' on the first loop
iteration, and all other reads cause an end of stream condition
(which also sets 'failbit'). That's why every character of the
string 'output' had this same value. (Casting this value to char
(Win XP, Pentium, gives character 'd').
Modified code: (my changes marked /* MKW */)
#include <iostream> // For std::cout
#include <string> // For std::string
#include <sstream> // For std::ostringstream
#include <iomanip> // For std::setfill
#include <cassert> /* MKW */
int
main()
{
// Set "input"
//
std::string input = "abcd";
std::cout << input << std::endl;
// Set "hexDump"
//
std::ostringstream oss;
oss << std::hex << std::setfill('0');
for(int i = 0; i < input.length(); i++)
{
int temp = input[i];
oss << std::setw(2) << temp;
}
std::string hexDump = oss.str();
assert(hexDump.length() == 2 * input.length());
std::cout << hexDump << std::endl;
// Set "output"
//
std::string output;
int numChars = hexDump.length() / 2;
output.resize(numChars);
std::istringstream iss(hexDump);
iss >> std::hex;
for(int i = 0; i < numChars; i++)
{
int temp;
iss >> std::setw(2) ;
if(!iss) /* MKW */
std::cerr << "iss error on setw\n"; /* MKW */
else /* MKW */
std::cerr << "OK on setw\n"; /* MKW */
iss >> temp; // BUG: Using setw DOES NOT WORK!!!
if(!iss) /* MKW */
std::cerr << "iss error on temp\n"; /* MKW */
else /* MKW */
{ /* MKW */
std::cerr << "OK on temp\n"; /* MKW */
std::cerr << " (temp == " << temp << ")\n"; /* MKW */
} /* MKW */
output[i] = temp;
}
std::cout << output << std::endl;
std::cout << char(0x61626364) << '\n'; /* MKW */
}
Thanks for actually compiling the program Mike!
Output:
abcd
61626364
OK on setw
OK on temp
(temp == 1633837924)
OK on setw
iss error on temp
iss error on setw
iss error on temp
iss error on setw
iss error on temp
dddd
d
.... so in my haste, I did err in my analysis. The stream
state was indeed 'fail', but not for the reason I originally
stated.
My apologies for any confusion.
But I still stand by my advice to always check stream
state after all operations.
-Mike