2
votes

I am trying to store the RGB values of a color into a struct named RGBTriple which is made up of three unsigned char Red, Green, Blue. I am reading in those values from a file and then parsing the string and assigning the correct value with the correct variable. Whenever I am reading in the unsigned char values the program is only reading in the first number even if the value is 255. After the width, height, and color are read in. I am creating a picture object. I do not have any trouble reading in the width or height.

Here is my RGBTriple

struct RGBTriple
{
    unsigned char Blue;
    unsigned char Green;
    unsigned char Red;

    RGBTriple();
    RGBTriple(unsigned char Blue, unsigned char Green, unsigned char Red);
};

and here is my main:

int pictureWidth, pictureHeight;
RGBTriple pictureColor;
string line;

    getline(input, line);
    istringstream iss(line);

    iss >> pictureWidth;
    iss >> pictureHeight;
    iss >> pictureColor.Red;
    iss >> pictureColor.Green;
    iss >> pictureColor.Blue;


    Picture newPicture(pictureWidth, pictureHeight, pictureColor);

Here is an example of my input: the first line is what is read in for the Picture Object.

200 200 255 255 255
Point 66 66 000 000 000
Line 100 150 50 50 255 000 000
Rectangle 50 25 55 33 000 000 000
RTriangle 10 80 50 30 000 000 000
Star 29 29 15 000 000 000
Diamond 120 120 20 000 000 000
Polygon 150 0 175 0 175 50 150 25 X X 000 000 000
Circle 40 89 26 000 000 000
2
Give us an example of what the line contains, what values you read, and what values you think you should have read. - David Schwartz

2 Answers

4
votes

The input operator is used

std::istream& operator >> (std::istream& stream, unsigned char& value) 

instead of

std::istream& operator >> (std::istream& stream, short& value)

or

std::istream& operator >> (std::istream& stream, int& value)

so it reads only 1 character. I suggesrt you to read short or int instread of unsigned chars than assign that values to structure like:

getline(input, line);
istringstream iss(line);

int iValue = 0;

iss >> pictureWidth;
iss >> pictureHeight;
iss >> iValue;
pictureColor.Red = iValue;
iss >> iValue;
pictureColor.Green = iValue;
iss >> iValue;
pictureColor.Blue = iValue;
2
votes

The operator overloads for >> interpret the stream according to the type of the operand. If the type is a char it will read a character code not an integer, so when presented with "255", the '2' will be read and the value will be 0x32.

It would probably be more appropriate to use std::uint8_t rather then char to store the RGB values, in which case another possibility is to explicitly overload the >> operator for std::uint8_t:

inline std::istream &operator >> (std::istream &is, std::uint8_t& c) 
{ 
    int iValue = 0; 
    is >> iValue; 
    c = iValue; 
    return is; 
}

But having done that, you are kind of forced to support std::int8_t and << as well; unless you are performing a lot of such operations, extracting to a numerical integer type and assigning as suggested by Mykola makes more sense.