Konwerter sytemów liczbowych wykonany w Dev++.

0

Witam,
piszę ten post w sprawie prośby o nakierowanie w rozwiązaniu problemu a mianowicie nie wiem gdzie stawiam błąd.
Stworzony prze zemnie program ma na celu konwersje liczbowe między różnymi systemami
Z początku po uruchomieniu wszystko działa idealnie wpisuje daną liczbę do wiersza poleceń i idealnie konwertuje mi między systemami.
Problem zaczyna się gdy chcę wpisać drugą liczbę gdyż po wpisaniu czego cokolwiek program zamyka się i muszę go uruchamiać ponownie.
Nasuwa się więc pytanie czy dało by się to jakoś poprawić.
Proszę o pomoc i pozdrawiam.
W złączniku znajduje się plik .cpp

 #include <iostream>
#include <string>

typedef unsigned long long uInt64;

uInt64 calculatePower(uInt64, uInt64);
uInt64 binaryToDecimal(std::string);
uInt64 hexadecimalToDecimal(std::string);
std::string decimalToBinary(uInt64);
std::string binaryToHexadecimal(std::string);

int main()
{
    std::string binary, hex;
    uInt64 decimal;
    uInt64 choice;

    std::cout << "\n\n                 WITAM W KONWERTERZE LICZBOWYM \n";
         std::cout << "\n\n BINARNYCH  \n";  
     std::cout << "\n\n DZIESIETNYCH  \n"; 
     std::cout << "\n\n SZESNASTKOWYCH  \n"; 
             std::cout << "\n\n PROSZE WYBRAC  JEDNA Z PONIZSZYCH KONWERSJI \n"; 
    std::cout << "\n\n* DZIESIETNY -> BINARNY & SZESNASTKOWY (1)\n";
    std::cout << "* DWOJKOWY -> DZIESIETNY & SZESNASTKOWY (2)\n";
    std::cout << "* SZESNASTKOWY -> BINARNY & DZIESIETNY (3)\n\n";
    std::cin >> choice;

    if (choice == 1)
    {
        std::cout << "\n> Decimal Input: ";
        std::cin >> decimal;
        std::string binaryOutput = decimalToBinary(decimal);
        std::string hexOutput = binaryToHexadecimal(binaryOutput);
        std::cout << "\n  Decimal Output: " << binaryOutput;
        std::cout << "\n  Hex Output    : " << hexOutput << "\n\n\n";
    }

    else if (choice == 2)
    {
        std::cout << "\n> Binary Input: ";
        std::cin.ignore();
        std::getline(std::cin, binary);
        uInt64 decimalOutput = binaryToDecimal(binary);
        std::string hexOutput = binaryToHexadecimal(binary);
        std::cout << "\n  Hex Output    : " << hexOutput;
        std::cout << "\n  Decimal Output: " << decimalOutput << "\n\n\n";

    }

    else if (choice == 3)
    {
        std::cout << "\n> Hex Input: ";
        std::cin.ignore();
        std::getline(std::cin, hex);
        uInt64 decimalOutput = hexadecimalToDecimal(hex);
        std::string binaryOutput = decimalToBinary(decimalOutput);
        std::cout << "\n  Binary Output : " << binaryOutput;
        std::cout << "\n  Decimal Output: " << decimalOutput << "\n\n\n";
    }

    system("PAUSE");
}

uInt64 calculatePower(uInt64 base, uInt64 exponent)
{
    uInt64 total = 1;

    for (uInt64 iter = 0; iter < exponent; iter++)
        total *= base;

    return total;
}

uInt64 binaryToDecimal(std::string binary)
{
    uInt64 decimal = 0;
    uInt64 exponent = 0;
    std::string::reverse_iterator iter;

    for (iter = binary.rbegin(); iter != binary.rend(); iter++)
    {
        if (*iter == '1')
            decimal += calculatePower(2, exponent);

        exponent++;
    }

    return decimal;
}

uInt64 hexadecimalToDecimal(std::string binary)
{
    uInt64 decimal = 0;
    uInt64 exponent = 0;
    std::string::reverse_iterator iter;

    for (iter = binary.rbegin(); iter != binary.rend(); iter++)
    {
        switch (*iter)
        {
        case '1':
            decimal += calculatePower(16, exponent);
            break;
        case '2':
            decimal += (2 * calculatePower(16, exponent));
            break;
        case '3':
            decimal += (3 * calculatePower(16, exponent));
            break;
        case '4':
            decimal += (4 * calculatePower(16, exponent));
            break;
        case '5':
            decimal += (5 * calculatePower(16, exponent));
            break;
        case '6':
            decimal += (6 * calculatePower(16, exponent));
            break;
        case '7':
            decimal += (7 * calculatePower(16, exponent));
            break;
        case '8':
            decimal += (8 * calculatePower(16, exponent));
            break;
        case '9':
            decimal += (9 * calculatePower(16, exponent));
            break;
        case 'A':
            decimal += (10 * calculatePower(16, exponent));
            break;
        case 'B':
            decimal += (11 * calculatePower(16, exponent));
            break;
        case 'C':
            decimal += (12 * calculatePower(16, exponent));
            break;
        case 'D':
            decimal += (13 * calculatePower(16, exponent));
            break;
        case 'E':
            decimal += (14 * calculatePower(16, exponent));
            break;
        case 'F':
            decimal += (15 * calculatePower(16, exponent));
            break;
        }

        exponent++;
    }

    return decimal;
}

std::string decimalToBinary(uInt64 decimal)
{
    std::string binary, newBinary = "";
    std::string::reverse_iterator iter;
    uInt64 remainder;

    while (decimal > 0)
    {
        remainder = decimal % 2;

        if (remainder == 0)
            binary += '0';
        else if (remainder == 1)
            binary += '1';

        decimal /= 2;
    }

    for (iter = binary.rbegin(); iter != binary.rend(); iter++)
    {
        newBinary += *iter;
    }

    return newBinary;
}

std::string binaryToHexadecimal(std::string binary)
{
    std::string hex, newHex = "";
    std::string::reverse_iterator iter;

    uInt64 incr = 1;

    uInt64 exponent = 0;

    uInt64 total = 0;

    for (iter = binary.rbegin(); iter != binary.rend(); iter++)
    {
        if (*iter == '1')
            total += calculatePower(2, exponent);

        if (incr == 4)
        {
            switch (total)
            {
            case 1:
                hex += '1';
                break;
            case 2:
                hex += '2';
                break;
            case 3:
                hex += '3';
                break;
            case 4:
                hex += '4';
                break;
            case 5:
                hex += '5';
                break;
            case 6:
                hex += '6';
                break;
            case 7:
                hex += '7';
                break;
            case 8:
                hex += '8';
                break;
            case 9:
                hex += '9';
                break;
            case 10:
                hex += 'A';
                break;
            case 11:
                hex += 'B';
                break;
            case 12:
                hex += 'C';
                break;
            case 13:
                hex += 'D';
                break;
            case 14:
                hex += 'E';
                break;
            case 15:
                hex += 'F';
                break;
            }

            incr = 0;
            exponent = -1;
            total = 0;
        }

        incr++;
        exponent++;
    }

    newHex += "0x";

    for (iter = hex.rbegin(); iter != hex.rend(); iter++)
    {
        newHex += *iter;
    }

    return newHex;
}

1

Musisz stworzyć pętlę while i wrzucić do niej większość (jeśli nie całość) kodu znajdującego się w main(). Następnie możesz stworzyć dodatkową opcję aby wyjść z programu używając instrukcji break.

2

Przyda się też usunąć te drabinki case'ów. Od biedy możesz napisać sobie funkcję z dwoma ifami, choć lepiej by było to wykonać na podstawie łańcucha znaków ze wszystkimi dopuszczalnymi znakami danego systemu (tu: heksadecymalnego).

0

Dziękuję za odpowiedzi myślę ze są poprawne jestem zielony i nie bardzo rozumiem o co w tym chodzi dokładnie do w którą linijkę mam to wkleić.?

0

Tak, są poprawne bo poprawnie działają, ale kodu napisałeś 20x za dużo – można to napisać o wiele krócej. Zobacz, chodzi o tę część:

switch (total)
{
case 1:
    hex += '1';
    break;
case 2:
    hex += '2';
    break;
case 3:
    hex += '3';
    break;
case 4:
    hex += '4';
    break;
case 5:
    hex += '5';
    break;
case 6:
    hex += '6';
    break;
case 7:
    hex += '7';
    break;
case 8:
    hex += '8';
    break;
case 9:
    hex += '9';
    break;
case 10:
    hex += 'A';
    break;
case 11:
    hex += 'B';
    break;
case 12:
    hex += 'C';
    break;
case 13:
    hex += 'D';
    break;
case 14:
    hex += 'E';
    break;
case 15:
    hex += 'F';
    break;
}

Wszystkie wartości w case'ach są po kolei. Do zmiennej hex dodajesz kolejne znaki, które można uzyskać prostą arytmetyką. Kody cyfr są koło siebie (od 48 do 57), kody tych sześciu liter też (od 65 do 70). Ale po co rozbijać to na warunki i przedziały, skoro możesz zadeklarować sobie stałą/zmienną, do której wpiszesz ciąg wszystkich znaków i pobierzesz ten odpowiedni.

Deklaracja ciągu może wyglądać tak:

const std::string hexDigits = "0123456789ABCDEF";

i teraz zamiast ogromnego switcha, wystarczy jedna prosta linijka:

hex += hexDigits[total]

I jak, lepiej? Zamiast pięćdziesięciu linijek są dwie. ;)


Drugi switch też można zlikwidować. Tyle że działa on odwrotnie – potrzeba znak (cyfrę lub literę) przerobić na liczbę. Tu z pomocą przychodzi metoda at, która robi dokładnie to co chcemy. Mamy już zadeklarowany ciąg znaków ze wszystkimi znakami szesnastkowymi, więc możemy go użyć drugi raz.

Dochodzimy do tego, że cały ten switch:

switch (*iter)
{
case '1':
    decimal += calculatePower(16, exponent);
    break;
case '2':
    decimal += (2 * calculatePower(16, exponent));
    break;
case '3':
    decimal += (3 * calculatePower(16, exponent));
    break;
case '4':
    decimal += (4 * calculatePower(16, exponent));
    break;
case '5':
    decimal += (5 * calculatePower(16, exponent));
    break;
case '6':
    decimal += (6 * calculatePower(16, exponent));
    break;
case '7':
    decimal += (7 * calculatePower(16, exponent));
    break;
case '8':
    decimal += (8 * calculatePower(16, exponent));
    break;
case '9':
    decimal += (9 * calculatePower(16, exponent));
    break;
case 'A':
    decimal += (10 * calculatePower(16, exponent));
    break;
case 'B':
    decimal += (11 * calculatePower(16, exponent));
    break;
case 'C':
    decimal += (12 * calculatePower(16, exponent));
    break;
case 'D':
    decimal += (13 * calculatePower(16, exponent));
    break;
case 'E':
    decimal += (14 * calculatePower(16, exponent));
    break;
case 'F':
    decimal += (15 * calculatePower(16, exponent));
    break;
}

wymieniamy znów na jedną, prostą linijkę:

decimal += hexDigits.at(*iter) * calculatePower(16, exponent);

1 użytkowników online, w tym zalogowanych: 0, gości: 1