2010-02-07 18 views
6

W porządku, przygotowałem trochę kodu, aby odwrócić szesnastkowe znaki w ramach zabawy, którą wymyśliłem.Co jest nie tak z moim algorytmem?

Oto co mam w tej chwili:

#include <stdio.h> 
int main() { 
    char a,b,c; 
    while (1) { 
     c = getchar(); 
     if (!feof(stdin)) { 
      a = c % 16; 
      b = (c - a)/16; 
      c = (a*16) + b; 
      putchar(c); 
     }else{break;} 
    } 
return 0; 
} 

To działa dobrze dla większości wartości. Na przykład 0xA0 staje się 0x0A itd ...

Jednak nie gra się dobrze z wartościami zaczynającymi się na "F".

0xF1 staje 0x10
0xFF staje 0xF0
etc ...

Czy ktoś może wskazać mi w dobrym kierunku?

+4

Potrzebujesz trochę miejsca na matematykę do pracy. użyj int dla aib, a nie char. Lub przełącz się na operacje bitowe (>><< i i |) zamiast operacji matematycznych. –

+0

@KennyTM: prawdopodobnie masz na myśli 'putchar (cc >> 4 | (cc i 0xf) << 4);' – mjv

+1

Jako dodatkowa uwaga: nie ma potrzeby odejmowania 'a' od' c' przed podzieleniem przez 16. 'b = c/16 "da dokładnie taki sam wynik. Tak właśnie działa podział liczb całkowitych w C. – AnT

Odpowiedz

5

Używasz podpisanego (na komputerze) typu danych. Przełącz na niepodpisany i powinien działać poprawnie.

+2

Masz rozwiązanie, ale zauważ, że 'char' może być podpisany lub unsigned w zależności od implementacji. – AraK

+0

Rzeczywiście! Dzięki! Teraz, ponieważ nigdy się nie dowiem, czy po prostu go używam. Nie miałbyś nic przeciwko tłumaczeniu, dlaczego podpisy są ważne w char's? Lub wskaż niektóre źródła? – tangrs

+0

Można by pomyśleć, że to trochę zbyt ogólny link, ale w rzeczywistości jest to bardzo interesujący artykuł: http: //en.wikipedia.org/wiki/Integer_ (computer_science) –

7

Jeśli znak jest podpisany w systemie, to gdy górny przekrój c jest f, c jest ujemny, a c% 16 daje wynik ujemny.

0

Nie wiem, dlaczego ktoś robi *, /, operacje%, podczas gdy proste operacje bitowe mogą robić takie rzeczy.

A = (C & 0x0F) < < 4;
b = (c & 0xF0) >> 4;
c = a | b;

+0

Wręcz przeciwnie. Nie wiem, dlaczego ktokolwiek użyłby operacji bitowych, jak to zrobią zwykłe ludzkie arytmetyki. – AnT

+0

Ponieważ dla maszyn są szybsze niż "zwykłe ludzkie arytmetyczne" – vrrathod

0

getchar i putchar powrotu i podjęcia int s. Nawet lepiej niż oni używają wartości char rzutowanej na unsigned char, co oznacza, że ​​dla wszystkich ważnych znaków putchar zwróci wartość dodatnią. Jest to potrzebne dla twojego algorytmu, ponieważ używasz % i w przeciwnym razie będziesz musiał polegać na zdefiniowanych przez implementację zachowaniach.

Po przypisaniu wartości getchar do int można sprawdzić, czy odczyt nie powiódł się z jakiegokolwiek powodu (nie tylko z końca strumienia) przez porównanie z EOF. Używanie feof nie jest wtedy konieczne - wcześniej nie było wystarczające.

E.g.

int main(void) { 
    int c; 
    while ((c = getchar()) != EOF) { 
     /* algorithm goes here */ 
     putchar(c); 
    } 
    return 0; 
} 
Powiązane problemy