You are not manipulating the bits correctly.
Values 0-15 require 4 bits max, but you are only shifting bits by 2 places, so you have room for handling values 0-3 only.
Lets break down your code, using 15 (1111
in binary) as an example.
This code:
data = data << 2; //makes room for the input
Takes the existing data (32, which is 00100000
in binary), shifts it 2 places to the left, becomes 10000000
.
Then this code:
data = data | input1;
Adds the input (which you are not restricting in any way, per the assignment) in the lower bits, becoming 10001111
.
This code:
output1 = data >> 2;
Shifts the total bits by 2 places to the right, becoming 00100011
, which as you can see loses the lower two bits of the previous input value that has been stored.
Then this code:
cout << output1;
Outputs the remaining bits as-is, which consists of bits from two different values merged together, producing 35 as output.
So, you need to bit-shift in both directions by either 4 bits (the minimum needed to handle values 0-15, taking up 16 bits total) or 8 bits (the maximum allowed to fit 4 values into 32 bits). And in the case of right-shifting, you need to mask out bits that you don't want in the output.
Try something more like this instead:
Using 4-bit storage (the minimum needed for handling values 0-15):
#include <iostream>
#include <limits>
using namespace std;
unsigned int getInput()
{
unsigned int in;
do
{
cout << "Input a number between 0-15 inclusive: ";
if (cin >> in)
{
if ((in >= 0) && (in <= 15))
break;
}
cin.clear();
cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
}
while (true);
return in;
}
int main()
{
unsigned int input1, input2, input3, input4;
unsigned int packit, output;
int which;
input1 = getInput();
input2 = getInput();
input3 = getInput();
input4 = getInput();
packit = (input4 << 12) | (input3 << 8) | (input2 << 4) | input1;
do
{
cout << "Which number to retrieve (1-4, or 0 to exit): ";
if (cin >> which)
{
if (which == 0)
break;
if ((which >= 1) && (which <= 4))
{
output = ((packit >> (4*(which-1))) & 0x0F);
cout << output << endl;
continue;
}
}
cin.clear();
cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
}
while (true);
return 0;
}
Using 8-bit storage (the maximum allowed, which would actually allow for handling values 0-255 max):
#include <iostream>
#include <limits>
using namespace std;
unsigned int getInput()
{
unsigned int in;
do
{
cout << "Input a number between 0-15 inclusive: "; // or 255
if (cin >> in)
{
if ((in >= 0) && (in <= 15)) // or 255
break;
}
cin.clear();
cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
}
while (true);
return in;
}
int main()
{
unsigned int input1, input2, input3, input4;
unsigned int packit, output;
int which;
input1 = getInput();
input2 = getInput();
input3 = getInput();
input4 = getInput();
packit = (input4 << 24) | (input3 << 16) | (input2 << 8) | input1;
do
{
cout << "Which number to retrieve (1-4, or 0 to exit): ";
if (cin >> which)
{
if (which == 0)
break;
if ((which >= 1) && (which <= 4))
{
output = ((packit >> (8*(which-1))) & 0xFF);
cout << output << endl;
continue;
}
}
cin.clear();
cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
}
while (true);
return 0;
}