HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Is this a correct use of the std::cout and std::cin basefields/conversions?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thisstdthebasefieldsconversionscincoutcorrectanduse

Problem

Considering the code that you can find at the bottom of this post, it's safe to say that this is a good example of how I can use different representations in different basefields correctly in C++ ?

I'm referring to the use of:

  • std::hex in the std::istringstream case



  • the use of std::cout.setf() and std::cout.unsetf() in the "output section"



In short is this correct for both input and output ?

This could possibly lead to some bug of some kind on some platforms ?

I also have a doubt about the use of an unsigned int to input a char, the basefield always cares about that ? I mean if I input f I would like to store 15 in decimals and not 102 from the ascii table.
(because a char is often implemented as an unsigned int)

Thanks.

```
// trying to determine what is the header available for unsigned ints
#if __cplusplus
#else
#include
#endif

#include
#include
#include
#include
#include
#include
#include

const static uint32_t fieldWidth = 2;

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

std::map bucket;
bucket["EAX"] = 0x0; // initializing bucket with default values
bucket["EBX"] = 0x0;
bucket["ECX"] = 0x0;
bucket["EDX"] = 0x0;

if (argc >= 2) {
switch (argc) {
case 2:
std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
break;
case 3:
std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
std::istringstream(argv[2]) >> std::hex >> bucket["EBX"];
break;
case 4:
std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
std::istringstream(argv[2]) >> std::hex >> bucket["EBX"];
std::istringstream(argv[3]) >> std::hex >> bucket["ECX"];
break;
case 5:
std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
std::istringstream(argv[2]) >> std::hex >> bucket["EBX"];
std::istringstream(argv[3]) >> std::hex >> bucket["ECX"];
std::istringstream(argv[4]) >> std::hex >> bucket["EDX"];
break;
default:
std::cout ::const_iterator

Solution

it's safe to say that this is a good example of how I can use different representations in different basefields correctly in C++ ?

I presume you stream manipulators.


I'm referring to the use of:

std::hex in the std::istringstream case
the use of std::cout.setf() and std::cout.unsetf() in the "output section"


These are examples of stream manipulators:

I would not do this:

#if __cplusplus 
#else
#include 
#endif


In one version you are putting the functions in the global namespace (stdint.h) the other you are putting the functions in the std namespace. This will cause problems and may give you different results on different compilers.

This seems like you are doing it the hard way:

if (argc >= 2) {
    switch (argc) {
    case 2:
      std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
      break;
    case 3:
      std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
      std::istringstream(argv[2]) >> std::hex >> bucket["EBX"];
      break;
    case 4:
      std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
      std::istringstream(argv[2]) >> std::hex >> bucket["EBX"];
      std::istringstream(argv[3]) >> std::hex >> bucket["ECX"];
      break;
    case 5:
      std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
      std::istringstream(argv[2]) >> std::hex >> bucket["EBX"];
      std::istringstream(argv[3]) >> std::hex >> bucket["ECX"];
      std::istringstream(argv[4]) >> std::hex >> bucket["EDX"];
      break;
    default:
      std::cout << "Too many arguments, exiting now\n";
      exit(EXIT_FAILURE);
    }


Why not a loop?

if (argc  4) {/*ERROR MSG AND EXIT*/}

 std::vector  mapIndex = { "EAX", "EBX", "ECX", "EDX" };
 for(int loop = 1; loop > std::hex >> bucket[mapIndex[loop-1]];
 }


The use of std::hex in this situation is correct.

It marks the input stream and the next value (if an hex integer) is correctly read.

Code Snippets

std::hex in the std::istringstream case
the use of std::cout.setf() and std::cout.unsetf() in the "output section"
#if __cplusplus < 201103L
#include <stdint.h>
#else
#include <cstdint>
#endif
if (argc >= 2) {
    switch (argc) {
    case 2:
      std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
      break;
    case 3:
      std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
      std::istringstream(argv[2]) >> std::hex >> bucket["EBX"];
      break;
    case 4:
      std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
      std::istringstream(argv[2]) >> std::hex >> bucket["EBX"];
      std::istringstream(argv[3]) >> std::hex >> bucket["ECX"];
      break;
    case 5:
      std::istringstream(argv[1]) >> std::hex >> bucket["EAX"];
      std::istringstream(argv[2]) >> std::hex >> bucket["EBX"];
      std::istringstream(argv[3]) >> std::hex >> bucket["ECX"];
      std::istringstream(argv[4]) >> std::hex >> bucket["EDX"];
      break;
    default:
      std::cout << "Too many arguments, exiting now\n";
      exit(EXIT_FAILURE);
    }
if (argc < 2 || argc > 4) {/*ERROR MSG AND EXIT*/}

 std::vector<std::string>  mapIndex = { "EAX", "EBX", "ECX", "EDX" };
 for(int loop = 1; loop < argc; ++loop)
 {
     // PS: just using mapIndex to keep it as close to your original
     //     code as possbile. If I had done this from scratch I would
     //     have just put the values into a four element array.

     std::istringstream(argv[loop]) >> std::hex >> bucket[mapIndex[loop-1]];
 }

Context

StackExchange Code Review Q#29107, answer score: 5

Revisions (0)

No revisions yet.