Wątek przeniesiony 2016-03-10 12:42 z C/C++ przez ŁF.

Zamiana liczb z systemu szesnastkowego na dziesiętny

0

Piszę program zamieniający liczbę z dowolnego systemu na dziesiętny metodą Hornera. Z binarnego i ósemkowego mam gotowe, jednak mam problem z szesnastkowym...

int n;
int suma;
		cout<<"Wybrano zamiane z systemu szesnastkowego na dziesietny."<<endl;
		cout<<endl;
		cout<<"Z ilu komponentow sklada sie liczba?"<<endl;
		cin>>n;
		cout<<endl; 
		cout<<"Wpisz liczbe w systemie szesnastkowym (max. 10 znakow):"<<endl;

		getchar ();

		char * tab = new char ( n );
    
		for(int i=0; i<n; i++)
        tab[i] = getchar(); // wczytywanie liczb znak po znaku,
		
		for(int i=0; i<n; i++)
		{
			if( ((tab[i] >= 'a') && (tab[i]<='z')) || ((tab[i]>='A') && (tab[i]<='Z'))) 
			{
				switch (tab[i])
					case 'a':
						tab[i]=10;
						break;
					case 'b':
						tab[i]=11;
						break;
					case 'c':
						tab[i]=12;
						break;
					case 'd':
						tab[i]=13;
						break;
					case 'e':
						tab[i]=14;
						break;
					case 'f':
						tab[i]=15;
						break;
					default:
						cout<<"zly znak"<<endl;

			
			}
			else if ( (tab[i]>='0') && (tab[i]<='9') ) 
			{
	                 tab[i]=tab[i];
			}
			suma=(suma+tab[i])*16;
		}
		
		suma=suma+tab[n-1];
		cout<<"Wynik: "<<suma<<endl;
		}

Nie działa w momencie zamieniania liter na liczby. Próbowałam też zamienić switcha na if'y, ale też nie działa - gdy dodałam cout<<tab[i], żeby wyświetliło co się dzieje w momencie wpisania litery 'a' na przykład, to nie wyświetlało nic, ale gdy napisałam cout<<tab[i]-1, wyświetlało 9...

1
  1. Za poznaj się z inkrementacją po jej nie rozumiesz: http://4programmers.net/Forum/1101404
  2. Czy kiedykolwiek widziałeś aby jakikolwiek program prosił o podanie długości liczby? wystarczy: char buff[9]; cin>>width(8)>>buff; więcej niż 8 znakowa liczba szesnastkowa i tak w inta się nie zmieści, no chyba ze z przodu same zera, ale w tym przypadku łatwiej człowiekowi będzie pominąć te zera niż zliczyć nie zera.
  3. W sumie nie potrzebujesz wczytywania całości do buforu wystarczy: char ch; ... while((ch=getchar())!='\n') ewentualnie int ch; while(((ch=getchar())!='\n')&&(ch!=EOF))
  4. Czy wiesz że C++ już to umie? cin>>hex>>suma; i voilà
  5. Prześledź co u ciebie się dzieje jak w liczbie będzie np znak dolara?
  6. funkcja która coś sensownego robi nie powinna smarować po ekranie, ma zwrócić sygnał błędu lub wywalić wyjątek.
  7. Zastanów się nad:
if(isdigit(ch)) dig=ch-'0';
else if(islower(ch)) dig=ch-'a'+10;
else if(isupper(ch)) dig=ch-'A'+10;
else dig=36;
if(dig>15) return -1;

ewentualnie:

static const char digits[]="0123456789ABCDEF";
cont char *ptr=strchr(digits,toupper(ch));
if(ptr) dig=ptr-digits;
else return -1;
  1. Z dowolnego systemu na dowolny zajmuje tylko tyle: http://4programmers.net/Forum/1005274
2
 char * tab = new char ( n );

to jest tworzenie jednego znaku o wartości n, więc potem wszelkie tab[i] to już UB. To co chciałeś to

char* tab = new char[n];

niemniej nie należy używać new (choćby z tego powodu, że nie umiesz go poprawnie używać - nie ma nigdzie delete) tylko std::vector

0
_13th_Dragon napisał(a):
  1. Za poznaj się z inkrementacją po jej nie rozumiesz: http://4programmers.net/Forum/1101404
  2. Czy kiedykolwiek widziałeś aby jakikolwiek program prosił o podanie długości liczby? wystarczy: char buff[9]; cin>>width(8)>>buff; więcej niż 8 znakowa liczba szesnastkowa i tak w inta się nie zmieści, no chyba ze z przodu same zera, ale w tym przypadku łatwiej człowiekowi będzie pominąć te zera niż zliczyć nie zera.
  3. W sumie nie potrzebujesz wczytywania całości do buforu wystarczy: char ch; ... while((ch=getchar())!='\n') ewentualnie int ch; while(((ch=getchar())!='\n')&&(ch!=EOF))
  4. Czy wiesz że C++ już to umie? cin>>hex>>suma; i voilà
  5. Prześledź co u ciebie się dzieje jak w liczbie będzie np znak dolara?
  6. funkcja która coś sensownego robi nie powinna smarować po ekranie, ma zwrócić sygnał błędu lub wywalić wyjątek.
  7. Zastanów się nad:
if(isdigit(ch)) dig=ch-'0';
else if(islower(ch)) dig=ch-'a'+10;
else if(isupper(ch)) dig=ch-'A'+10;
else dig=36;
if(dig>15) return -1;

ewentualnie:

static const char digits[]="0123456789ABCDEF";
cont char *ptr=strchr(digits,toupper(ch));
if(ptr) dig=ptr-digits;
else return -1;
  1. Z dowolnego systemu na dowolny zajmuje tylko tyle: http://4programmers.net/Forum/1005274
  1. Chodzi tylko o i++ / ++i?
  2. Ok, tu tworzę tablicę buff i wczytuję do niej znaki.
  3. Rozumiem, że ten fragment odpowiada ze to, że wczytywanie znaków zostaje zakończone, po wciśnięciu Enter. Tylko jak zmienna char ch ma się do tej tablicy?
    Nie powinno być coś w stylu
while ((buff[i]=getchar())!='\n')

?
4. Wiem, ale nie chodzi mi o gotową funkcję.
5. Jak na razie to dziwne rzeczy dzieją się przy wpisaniu jakiegokolwiek znaku.
7. Wtedy trzeba te 3 funkcje zdefiniować na samym początku? Jak to ma wyglądać? Co to jest dig?

Dopiero zaczynam programować i to, co dla Ciebie pewnie jest oczywiste, dla mnie nie jest. Dlatego o ile to możliwe, proszę o dość łopatologiczne wytłumaczenie.
Jeszcze nie bardzo rozumiem funkcje, dlatego chciałam napisać program bez używania ich.

0

Ad 1. o --i / i-- również no i oczywiście nie tylko o i
Ad 2. Tak naprawdę nie potrzebujesz wcale tablicy.
Ad 3 i 7.

int ch,suma=0;
while(((ch=getchar())!='\n')&&(ch!=EOF))
  {
   static const char digits[]="0123456789ABCDEF";
   cont char *ptr=strchr(digits,toupper(ch));
   if(ptr) suma=suma*10+(ptr-digits); // dig to kolejny znak (digit)
   else break; // tu przerywamy działanie bo kolejny znak nie jest liczbą.
  }
if((ch!='\n')&&(ch!=EOF)) cout<<"przerwano z powodu błędu"<<endl;
else cout<<"W postaci dziesiętnej: "<<suma<<endl;

Staraj się zbierać wiedzę nawet ze szczątków, więc eksperymentuj i zastanawiaj się zamiast zadawać kolejne pytania.

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