Sprawdzanie/zamiana : liczba dzieś,dwojkitp na dziesietna

0

Witam. A wiec moim zadaniem było napisanie programu ktory sprawdza czy dany ciąg znaków jest liczbą dziesietną czy dwojkowa, osemkowa , szesnastkową. I jeśli jest to żeby zamieniał na dziesiętną. A wiec napisałem cos takiego i program działa ale moje pytanie polega jak można skrócić zamianę z Szesnastowego na dwojkowy oraz jakie dodakowe warunki sprawdzania czy to jest liczba dziesiętna można dodać?

#include <stdio.h>
#include <stdlib.h>
#define M 100
#include <string.h>
#include <ctype.h>
#include <math.h>


void czyDziesietna(char *wsk, int *s)
{
    int i, j=0;

    for(i=0; i<strlen(wsk); i++)
    {
        if(wsk[i]==46 || (wsk[i]>=48 && wsk[i]<=57) || (wsk[i]==69 && (wsk[i+1]==43 || wsk[i+1]==45) || (wsk[i]==101 && (wsk[i+1]==43 || wsk[i+1]==45)))) j++;
    }
    if(j==strlen(wsk)) *s=1;
}

void czyDwojkowa(char *wsk, int *s)
{
    int i, j=0;
    if(wsk[0]==48) j++;
    if(wsk[1]==98) j++;

    for(i=2; i<strlen(wsk); i++)
    {
        if(wsk[i]==48 || wsk[i]==49) j++;
    }
    if(j==strlen(wsk)) *s=2;
}

void czyOsemkowa(char *wsk, int *s)
{
    int i, j=0;
    if(wsk[0]==48) j++;
    for(i=1; i<strlen(wsk); i++)
    {
        if(wsk[i]>=48 && wsk[i]<=55) j++;
    }
    if(j==strlen(wsk)) *s=3;
}

void czySzesnastkowa(char *wsk, int *s)
{
    int i, j=0;
    if(wsk[0]==48) j++;
    if(wsk[1]==88 || wsk[1]==120) j++;

    for(i=2; i<strlen(wsk); i++)
    {
        if((wsk[i]>=48 && wsk[i]<=56) || (wsk[i]>=65 && wsk[i]<=70) || (wsk[i]>=97 && wsk[i]<=102)) j++;
    }
    if(j==strlen(wsk)) *s=4;
}

int dwojDzies(char *wsk)
{
    int i, dzies=0, j=0;
    for(i=0; i<strlen(wsk)-2; i++)
    {
        if(wsk[strlen(wsk)-1-i]!='0')
        dzies+=pow(2,j);
        j++;
    }
    return dzies;
}

int osemDzies(char *wsk)
{
    int i, dzies=0, j=0, z=0;

    for(i=0; i<strlen(wsk)-1; i++)
    {
        switch(wsk[strlen(wsk)-1-i])
        {
            case '0': z=0; break;
            case '1': z=1; break;
            case '2': z=2; break;
            case '3': z=3; break;
            case '4': z=4; break;
            case '5': z=5; break;
            case '6': z=6; break;
            case '7': z=7; break;
        }
        dzies+=z*pow(8,j);
        j++;
    }
    return dzies;
}

int szesnDzies(char *wsk)
{
    int i, dzies=0, j=0, z=0;
    for(i=0; i<strlen(wsk)-2; i++)
    {
        switch(wsk[strlen(wsk)-1-i])
        {
            case '0': z=0; break;
            case '1': z=1; break;
            case '2': z=2; break;
            case '3': z=3; break;
            case '4': z=4; break;
            case '5': z=5; break;
            case '6': z=6; break;
            case '7': z=7; break;
            case '8': z=8; break;
            case '9': z=9; break;
            case 'a': z=10; break;
            case 'A': z=10; break;
            case 'b': z=11; break;
            case 'B': z=11; break;
            case 'c': z=12; break;
            case 'C': z=12; break;
            case 'd': z=13; break;
            case 'D': z=13; break;
            case 'e': z=14; break;
            case 'E': z=14; break;
            case 'f': z=15; break;
            case 'F': z=15; break;
        }
        dzies+=z+pow(16,j);
        j++;
    }
    return dzies;
}

int main(int argc, char **argv)
{
   char tab[M];
   printf("Podaj wyrazenie: \n");
   gets(tab);
   int s=0;

           czyDziesietna(tab, &s);
           czyDwojkowa(tab, &s);
           czyOsemkowa(tab, &s);
           czySzesnastkowa(tab, &s);

   switch(s)
   {
       case 1: printf("Liczba w systemie dziesietnym i wynosi: %s", tab); break;
       case 2: printf("Liczba w systemie dwojkowym i wynosi: %d", dwojDzies(tab)); break;
       case 3: printf("Liczba w systemie osemkowym i wynosi: %d", osemDzies(tab)); break;
       case 4: printf("Liczba w systemie szesnastkowym i wynosi: %d", szesnDzies(tab)); break;
       default: printf("Ciag znakow nie jest liczba"); break;
   }
   return 0;
}

Tytuły funkcji mówią same za siebie więc chyba komentarze nie są potrzebne. Z góry dzięki za pomoc!

0

Zasadnicza wada programu jest taka: czytasz liczby jako stringi, nie ma więc ograniczeń na wielkość. Jeżeli wprowadzona liczba nie jest dziesiętna, to przeliczasz korzystając z typu int, bardzo łatwo o przekroczenie zakresu i błędny wynik. Co wyświetlisz gdy użytkownik wpisze 0xab7777777ffaaaaaaaaaaaa?

0

Nie programuję w C/C++ ale wydaje mi się, że liczbę 0123 program zinterpretuje jako ósemkową.
Nie da się jednoznacznie stwierdzić czy to jest liczba ósemkowa czy dziesiętna.
Jeśli się mylę to proszę o sprostowanie.

0

takie mam założenia dotyczące sprawdzania:

  • systemie dziesiętnym może wystąpić "." oraz cyfry 0 - 9 lub w formacie naukowym "e" (małe lub duże) wraz z "+" lub "-", np. 10.67e+2, 35E-15.
  • systemie dwójkowym liczba zaczyna się od "0b" i występują cyfry 0 i 1, np. 0b1010001.
  • w systemie ósemkowym liczba zaczyna się od "0" i występują cyfry 0 - 7, np. 0765601.
  • w systemie szesnastkowym liczba zaczyna się "0x" (lub "0X") i wystąpić mogą cyfry 0 - 9 i znaki (małe lub duże) A - F, np. 0xFEDfF901.
0

W c/c++ liczbę ósemkową poprzedza się pojedynczym 0, czyli jest ok.

0
Sarrus napisał(a)

W c/c++ liczbę ósemkową poprzedza się pojedynczym 0, czyli jest ok.

Ale czy zabrania się poprzedzania liczby dziesiętnej pojedynczym 0? Jeśli nie to lepiej takiego systemu ósemkowego nie używać.

0

w zamianie z szesnastkowego na dziesietny był blad, ale juz poprawiłem

dzies+=z*pow(16,j); 

Bo bylo + zamias *
no dobra ale czy ktos mi moze powiedzieć jak uprości tę zamianę z szesnastkowego na dziesiętny?

0

Imo, ten program trzeba napisać od nowa. a nie uprościć. Sprawdziłeś reakcję swojego programu na Oxfffffffffffffffffff?

0

jak widzę to program się spuje w szesnastkowym jeśli po 0x jest więcej niz 6 znaków

0

Optymista, program działa poprawnie tylko dla "niezbyt wielkich" liczb dwójkowych, ósemkowych i szesnastkowych. Bez ograniczeń działa dla liczb dziesiętnych - liczby dziesiętne są wypisywane bez żadnych przekształceń. w pozostałych przypadkach następuje, dla dużych liczb, przepełnienie.

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