1

I have three programs. the code of programA is shown below:

#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <locale>
using namespace std;
int _tmain( void )
{
    wstringstream s2;    
    TCHAR waTemp2[4] = {0xA0, 0xA1, 0x00A2, 0xA3};
    for (int i = 0; i < 4; i++)
    {
    s2<< hex <<(unsigned int)waTemp2[i] << " ";  
    }
    wstring strData2 =  s2.str();
    wcout << strData2.c_str() <<endl; 
    return 0;
}

here is the output:

a0 a1 a2 a3

the code of programB is shown below:

#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <locale>
using namespace std;
int _tmain( void )
{
    wstringstream s2;    
    TCHAR waTemp2[4] = {0xA0, 0xA1, 0x00A2, 0xA3};
    for (int i = 0; i < 4; i++)
    {
    s2<< hex << waTemp2[i] << " ";  
    }
    wstring strData2 =  s2.str();
    wcout << strData2.c_str() <<endl; 
    return 0;
}

here is the output:

????

the code of the programC is shown below:

#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <locale>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    wstringstream s2;    
    TCHAR waTemp2[4] = {0xA0, 0xA1, 0x00A2, 0xA3};
    for (int i = 0; i < 4; i++)
    {
    s2 << std::wios::hex <<(unsigned int)waTemp2[i] << " "; 
    }
    wstring strData2 =  s2.str();
    wcout<< strData2.c_str() <<endl;
    return 0;
}

here is the output:

2048160 2048161 2048162 2048163

could you tell me the reasons the difference between std::wios::hex and std::hex, std::hex << waTemp2[i] and std::hex << (unsigned int)waTemp2[i] resulted in different of the output.

thank you very much!

yaoike
  • 11
  • 1

1 Answers1

1

std::hex is a manipulator. It sets the stream to output hex when you pass an integer. It is equivalent to calling setf(std::wios::hex, std::wios::basefield); on the stream (assuming wide streams). For example, try the following modification of your code. You should see the same results.

wchar_t waTemp2[4] = {0xA0, 0xA1, 0x00A2, 0xA3};
s2.setf(std::wios::hex, std::wios::basefield);
for (int i = 0; i < 4; i++)
{
    s2 << (unsigned)waTemp2[i] << " ";  
}

std::wios::hex is a constant number used as a bitmask flag. Do not confuse it with a manipulator which sets the stream. On coliru for example the following prints 8.

std::cout << std::wios::hex;

It is used as a bitmask to update the format flags on the stream. It will defined something like the following (see the real definition in libstdc++ here):

enum fmtflags
{
   _hex = 1L << 3,
};

class ios_base
{
    static const fmtflags hex = _hex;
};

The reason you are seeing 2048160 2048161 2048162 2048163 is it is just printing out the numbers of std::wios::hex and (unsigned int)waTemp2[i]. Add a space in between to see s2 << std::wios::hex << " " << (unsigned int)waTemp2[i] << " ";

The problem with s2 << hex << waTemp2[i] << " "; is std::hex is only used for integers. Since wchar_t is not an integer, it just prints the corresponding character.

Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • @yaoike: What are the two questions? – Jesse Good Jul 03 '13 at 06:24
  • thank you very much. i still have three questions. 1. you said std::hex is a manipulator. It sets the stream to output hex when you pass an integer. why does it work when i pass an integer rather than TCHAR,i could not find std::hex manipulator can take integer in C++ reference[link](http://www.cplusplus.com/reference/ios/hex/?kw=hex). 2. To code `s2<< hex <<(unsigned int)waTemp2[i] << " ";`,is there any way to instead of it, in the `ios_base& hex (ios_base& str);` forms – yaoike Jul 03 '13 at 07:37
  • 3. I didn't understand this sentence which you said。"However, the result are undefined because **0xA0**, etc. is greater than the number of bits in the value **std::wios::hex**.", Is the number of bits in the value **std::wios::hex** equal 64? It doesn't work when I use **0x05** to replace **0xA0**, could you do an example? – yaoike Jul 03 '13 at 07:38
  • @yaoike: 1) Your link clearly says so: `**integral numerical values** inserted into the stream are expressed in hexadecimal base `. 2) I'm not sure what you are asking, do you mean call it like a function `std::hex(std::wcout);`? 3) Sorry, I made a mistake, it isn't the bitwise left shift, it is just printing the number. For example, the `160` in `2048160` is just `0xA0` in decimal, and the same goes for the other ones (see my updated answer). – Jesse Good Jul 03 '13 at 08:00
  • 2)yes. 3)OK,i am seeing **2048 160 2048 161 2048 162 2048 163** ,but why is **2048** rather than **8**, you said: `enum fmtflags { _hex = 1L << 3, }; class ios_base { static const fmtflags hex = _hex; };` – yaoike Jul 03 '13 at 08:52
  • @yaoike: What compiler are you using? The number `8` was for libstdc++ gcc only. **EDIT** Nevermind, I see you are using MSVC from `"stdafx.h"`. The number depends on the implementation (it is not set). [See here](http://en.cppreference.com/w/cpp/io/ios_base/fmtflags) and notice it says **implementation defined**. – Jesse Good Jul 03 '13 at 08:55
  • @yaoike: [Like this example?](http://coliru.stacked-crooked.com/view?id=9b8b3c55d8c7885354f4bb370eb274f9-f674c1a6d04c632b71a62362c0ccfc51). Sorry, I cannot fully understand. – Jesse Good Jul 03 '13 at 09:13
  • No, Not **s2.operator<<(std::hex).operator<<((unsigned)waTemp2[i]);** ,like this **s2 << std::hex(ios_base& str)**. what is **std::hex**, a manipulator or [a function](http://www.cplusplus.com/reference/ios/hex/?kw=hex)? – yaoike Jul 03 '13 at 09:27
  • @yaoike: This is getting long, but the important point is a stream manipulator **is a** function. Please read [How do the stream manipulators work?](http://stackoverflow.com/questions/4633864/how-do-the-stream-manipulators-work). When you do `s2 << std::hex` you are passing a pointer to a function to the `operator<<` which calls the function internally. You cannot call `std::hex` the way you have it. – Jesse Good Jul 03 '13 at 09:47
  • Also, I don't mind trying to help, but if you have more questions. Please ask them as a separate question, but [here is an example of a custom manipulator](http://coliru.stacked-crooked.com/view?id=4ea48c175179bd9410cfd05bb8d30bb4-f674c1a6d04c632b71a62362c0ccfc51). See how I made it a function and passed it to the stream? – Jesse Good Jul 03 '13 at 09:52
  • I see. A thousand thanks for taking the time to answer these questions. :) This is my first question in here. I was so happy to ask my questions on this site. – yaoike Jul 03 '13 at 10:30