Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OK, either I'm crazy or there is a bug in IBM's compiler

I'll buy anyone a beer if they can tell me why streamstream<<(char) ignores 0x05. This program is producing 000102030406070809E280081150121314

The expected output I think would have been something more like: 00010203040506070809E2800811050505050505050550121314

IBM i (a.k.a. AS/400) C++ compiler, running on V7R1.

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <stdint.h>

using namespace std;


typedef int8_t byte;

int main(int argc, char* argv[])
{
    stringstream sstr2;
    sstr2 << char(0x00);
    sstr2 << char(0x01);
    sstr2 << char(0x02);
    sstr2 << char(0x03);
    sstr2 << char(0x04);
    sstr2 << char(0x05);
    sstr2 << char(0x06);
    sstr2 << char(0x07);
    sstr2 << char(0x08);
    sstr2 << char(0x09);
    sstr2 << char(0xe2);
    sstr2 << char(0x80);
    sstr2 << char(0x08);
    sstr2 << char(0x11);
    sstr2 << char(0x05);
    sstr2 << char(0x05);
    sstr2 << char(0x05);
    sstr2 << char(0x05);
    sstr2 << char(0x05);
    sstr2 << char(0x05);
    sstr2 << char(0x05);
    sstr2 << char(0x05);
    sstr2 << char(0x50);
    sstr2 << char(0x12);
    sstr2 << char(0x13);
    sstr2 << char(0x14);

    char c;
    sstr2 >> c;
    while (sstr2.good()) {
        cout << hex << uppercase << setw(2) << setfill('0') << (int)c;
        sstr2 >> c;
    }
    cout << endl;
}
like image 329
Kelly Beard Avatar asked Jul 29 '14 20:07

Kelly Beard


1 Answers

It's time to distil the hive-mind comment thread into something resembling a useful answer...

0x05 is giving you problems because your AS/400 uses EBCDIC encoding, and that's a tab character. On ASCII systems, character 0x09 (tab) gives a similar problem.

The << and >> operators for stringstream are for formatted input and output, so whitespace characters (e.g. tabs, space - and line endings) can get altered.

You should use the option std::stringstream::binary when you construct the stream, to prevent newline sequences getting changed.

Also, you have to tell the formatted read operator not to skip whitespace in the stream, using the noskipws I/O manipulator.

Alternatively, you could just save your data to a generic container (e.g. std::vector, or std::string) and avoid this hassle entirely.

like image 66
Roddy Avatar answered Oct 23 '22 14:10

Roddy