If I understand what you are asking, you want to be able to repeat entering the number of bits and outputting the string holding the representation of the bits and the decimal value. You want all variables to be reset between different iterations for decVal
. To make that possible, along with fixing a few errors, you simply need to wrap what you are currently doing in another loop so that for each iteration of the outer loop, you process all the bits you like an come up with a final decVal
to output.
Before looking at a solution, as mentioned in the comment above, void main()
is only valid for a freestanding environment (e.g. no Operating System, like a microcontroller, etc..) Otherwise, the allowable declarations for main
for are int main (void)
and int main (int argc, char *argv[])
(which you will see written with the equivalent char **argv
). See What should main() return in C and C++?
While convenient, you will also want to read Why is “using namespace std;” considered bad practice? and so you understand the difference between '\n'
and std::endl
, go ahead a look at C++: “std::endl” vs “\n”
One thing you must always do with EVERY input is to validate it succeeds by checking the stream-state after the attempted input and BEFORE you use the variable filled by the input. If a matching failure occurs, failbit
will be set and you must clear the error bit before attempting your next input. You can handle the error any way you like, from either ending the program, or by clearing the error bit and removing the characters that caused the problem with .ignore()
(examples of both are shown below). Essentially, at minimum, you need something like:
if (!(std::cin >> n)) { /* validate EVERY user input */
std::cerr << "invalid unsigned input -- exiting.\n";
return 1;
}
(note: instead of just calling .ignore()
, you should use its full and proper invocation removing up to the maximum number of values for any particular circumstance. When reading from a file-steam, that is: std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
)
Now for your program setup, you can essentially just use a continual loop around code similar to what you have and just provide a mechanism to exit the outer loop when the user is done entering values. For example, using a simple while(1)
loop and having the user enter anything other than a valid number for n
, you could do:
while (1) { /* outer loop - loop continually */
size_t n; /* declare variables within loop */
uint32_t decVal = 0;
std::string originalnum {};
std::cout << "\nenter no. of bits ('q' to quit): ";
if (!(std::cin >> n)) { /* validate EVERY user input */
std::cerr << "invalid unsigned input -- exiting.\n";
return 1;
}
Note: all variables are declared inside the loop, so for each iteration, the variables are declared and initialized each time. Above the user is told to press 'q'
to quit -- but can enter anything that is not a valid number to exit. That will simply exit the program returning control to the calling process.
Look at your code, there really isn't any need for the pow()
function to compute decVal
from the user's entry of 0
's and 1
's. Instead, you can simply declare decVal
as an unsigned
value (an exact with uint32_t
is used below) and simply use Left-Shift to shift each input by the current loop counter number of bits.
Using the left-shift described above to compute decVal
(ensuring decVal
is initialized to zero when declared), and adding the user inputs to the front of the string to preserve LSB first order, you could do:
#include <iostream>
#include <iomanip>
#include <string>
#include <limits>
#include <climits>
int main (void)
{
while (1) { /* outer loop - loop continually */
size_t n; /* declare variables within loop */
uint32_t decVal = 0;
std::string originalnum {};
std::cout << "\nenter no. of bits ('q' to quit): ";
if (!(std::cin >> n)) { /* validate EVERY user input */
std::cerr << "invalid unsigned input -- exiting.\n";
return 1;
}
if (n > sizeof (uint32_t) * CHAR_BIT) { /* validate EVERY value in range */
std::cerr << " error: n exceeds no. of bits avaialble.\n";
return 1;
}
for (size_t i = 0; i < n;) { /* inner loop, process bits */
uint32_t bit;
std::cout << " bit" << std::setw(2) << i << ": ";
if (!(std::cin >> bit) || bit > 1) {
std::cerr << " error: invalid bit input.\n";
std::cin.clear();
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
decVal += bit << i; /* no need for pow(), left-shift */
originalnum.insert(0, 1, bit + '0'); /* build originalnum each iteration */
i++; /* increemnt on good input */
}
/* result */
std:: cout << "The decimal equivalent of " << originalnum <<
" = " << decVal << '\n';
}
}
(note: Numeric limits -- cppreference.com shows the header files needed for each limit used)
Example Use/Output
Below is input and output similar to what you show, but with prompts added to guide the user, and error handling implemented to ensure only valid 0
's and 1
's are taken as input:
$ ./bin/decval
enter no. of bits ('q' to quit): 3
bit 0: 1
bit 1: 1
bit 2: 0
The decimal equivalent of 011 = 3
enter no. of bits ('q' to quit): 3
bit 0: 1
bit 1: 0
bit 2: 0
The decimal equivalent of 001 = 1
enter no. of bits ('q' to quit): 3
bit 0: 1
bit 1: 0
bit 2: pickles
error: invalid bit input.
bit 2: 1
The decimal equivalent of 101 = 5
enter no. of bits ('q' to quit): q
invalid unsigned input -- exiting.
Look things over and let me know if you have further questions or if I misunderstood your intent.