Binary to decimal converter I started a few weeks ago to learn C++ online. I just made a little binary &rightarrow; decimal program. Here is my code:

#include &lt;iostream&gt;

using namespace std;

int main()
{
    int i,j=1;
    long long decimal=0, powerOfTwo=1;
    cin&gt;&gt;i;
    char binary[i];
    i*=2;
    while (i)
    {
        if (i &gt; j)
        {
           cin&gt;&gt;binary[j];
           ++j;
        }
        else
        {
            cout&lt;&lt;binary[i];
            if (i%4 == 1) //adds a space after 4 numbers (eg. 1011 0111 instead of 10110111)
                cout&lt;&lt;" ";
            if (binary[i] == '1')
                decimal += powerOfTwo;
            powerOfTwo *= 2;
        }
        --i;
    }
    cout&lt;&lt;"in ten base is equal to "&lt;&lt;decimal;
    return 0;
}


So I want to know, am I heading in the right direction? Please let me know what I am not doing good or any kind of suggestion.
What would Bob do?

You've written an interactive program, but the user does not know what your program does. Therefore, Bob&mdash;the generic user&mdash;might accidentally write "test" instead of a number, and suddenly your program runs wild.

A first step in the right direction would be to tell the user what your program will do&mdash;as long as its interactive. Note that this is not C++ specific.

We can do so by starting with:

cout &lt;&lt; "This program converts a binary number to a decimal one\n"
        "Please state the length of your number: ";


But that's error prone. First of all, Bob might not know how long the binary number is. Try to check whether 1101011010101101 is 14 or 15 characters long. That's a trick question, those are 16 characters.

So instead, just let Bob write anything and then check how long it is and whether it was really a binary number.

Prefer std::string to char[N]

Instead of char binary[i], we will use a std::string binary. This makes the input a lot easier. However, to handle the input easier, let's write a function. Actually, let's write two:

bool is_binary_number(const std::string&amp; binary){
    return std::all_of(binary.begin(), binary.end(), [](char c){
        return c == '0' || c == '1';
    });
}


That's using C++11's all_of in combination with a lambda. In case you don't know that yet, here's the same variant written in a range-based for loop:

bool is_binary_number(const std::string&amp; binary){
    for(char c : binary) {
        if(c != '0' &amp;&amp; c != '1') {
            return false;
        }
    }
    return true;
}


But this is C++11 syntax. In case you're not familar with C++11 at all, it's almost the same as

bool is_binary_number(const std::string&amp; binary){
    for(size_t i = 0; i &lt; binary.size(); ++i) {
        if(binary[i] != '0' &amp;&amp; binary[i] != '1') {
            return false;
        }
    }
    return true;
}


In case you don't know std::string &amp; yet, that's a reference. A reference is an alias to an already existing object. A const reference is an alias where we cannot change the value:

int        value = 15;
int&amp;       ref   = value;
const int&amp; cref  = value;

ref = 12;

std::cout &lt;&lt; value &lt;&lt; std::endl; // prints 12, since we changed it via ref
std::cout &lt;&lt; cref  &lt;&lt; std::endl; // prints 12, since we changed it via ref

// does not compile:
cref = 7;           // error; this reference is read only!


The details are a little bit more complicated, but in the end, when we call is_binary_number(on_a_string), we won't make a copy of on_a_string.

Either way, now that we have a function to check whether a string is a binary number, we can write our function to ask Bob for input:

std::string ask_binary_number() {
    std::cout &lt;&lt; "Please enter a binary number: ";

    while(true) {
        std::string input;
        std::cin &gt;&gt; input;

        if(is_binary_number(input)) {
            return input;  
        } else {
            std::cout &lt;&lt; "That wasn't a binary number, try again: ";
        }
    }
}


We can now use this in main:

#include &lt;iostream&gt;
#include &lt;string&gt;        // necessary for std::string

int main () {
    std::string binary = ask_binary_number();

    ...
}


Note that we don't need to touch main at all if we want to change the input method later on. We only need to change ask_binary_number. This makes it easy to ask the user for another number, or re-use ask_binary_number in another project.

Exercise: Usually, you don't want leading zeroes in binary numbers. Which function do you have to change to not allow leading zeroes in the result of ask_binary_number? What changes are necessary?

Keep it simple and stupid

In your for loop, you do two things at once: you print the binary number and convert the number to a decimal. Unless you know that this is a bottleneck in your program and you need cache locality or something similar to keep your code fast, do one thing and one thing only. This makes it a lot easier to change the code later without breaking something else.

We can split this functionality again into two functions:

void print_binary_with_spaces(const std::string &amp; binary, size_t digits = 4){
    // exercise; almost solved by your own code
}

unsigned long binary_to_decimal(const std::string &amp; binary){
    // exercise; almost solved by your own code
}


If you implement all functions given above, you end up with the following main:

#include &lt;iostream&gt;
#include &lt;string&gt;

// functions here (either completely or only their declaration)

int main() {
    std::cout &lt;&lt; "This program converts a binary number to a decimal one." &lt;&lt; std::endl;
    std::string binary = ask_binary_number();

    std::cout &lt;&lt; "Your binary number ";

    print_binary_with_spaces(binary);

    std::cout &lt;&lt; " is " &lt;&lt; binary_to_decimal(binary) &lt;&lt; "in decimal"
              &lt;&lt; std::endl;
}


Note that all complex interactions are moved into functions. However, as you have seen in ask_binary_number and is_binary_number those functions aren't complex themselves either. Keeping things simple is a principle (KISS) that's often applied, as is splitting the functionality (separation of concerns).

A concrete example of overly complex code

Why am I pointing to simplicity? Because your while loop is overly complex:

i = i * 2;
j = 1;
while (i)
{
    if (i &gt; j)        
    {
       ...            // lets call this A
       ++j;
    }
    else
    {
        ...          // lets call this B
    }
    --i;
}


Essentially, you have the following loops:

for(j = 0; j &lt; i; ++j)
{
    A; // see above
}

for(--i; i &gt; 0; --i)
{
    B; // see above
}


If we used that in your program, it would look like this:

for(int j = 0; j &lt; i; ++j){
    cin &gt;&gt; binary[j];
}

while(i-- &gt; 0){
    cout &lt;&lt; binary[i];
    if (i%4 == 1) 
        cout &lt;&lt; " ";
    if (binary[i] == '1')
        decimal += powerOfTwo;
    powerOfTwo *= 2;
}


This is not only easier to understand, it's even shorter. So try to keep your loops simple.