2010-02-07 2 views
6

In Ordnung, ich habe Code ausgearbeitet, um Hex-Zeichen umzukehren, als Teil einer lustigen Übung, die ich erfunden habe. HierWas ist falsch an meinem Algorithmus?

ist das, was ich im Moment haben:

#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; 
} 

Es funktioniert gut für die meisten Werte. Zum Beispiel wird 0xA0 zu 0x0A usw. ...

Allerdings spielt es nicht gut mit Werten ab, die mit "F" beginnen.

0xF1 wird 0x10
0xFF 0xF0
etc wird ...

jemand mich in die richtige Richtung zeigen kann?

+4

Sie brauchen etwas Spielraum für Ihre Mathematik zu arbeiten. Benutze int für a und b anstatt char. Oder wechseln Sie zu bitweisen Operationen (>><< & und |) anstelle von mathematischen Operationen. –

+0

@KennyTM: du meinst wahrscheinlich 'putchar (cc >> 4 | (cc & 0xf) << 4);' – mjv

+1

Als zusätzliche Anmerkung: es ist nicht notwendig, 'a' von' c' zu subtrahieren, bevor dividiert durch 16. 'b = c/16' ergibt genau das gleiche Ergebnis. So funktioniert Integer Division in C. – AnT

Antwort

5

Sie verwenden einen signierten (auf Ihrer Maschine) -Datentyp. Schalten Sie es auf unsigned und es sollte ordnungsgemäß funktionieren.

+2

Sie haben die Lösung, aber beachten Sie, dass 'char' abhängig von der Implementierung signiert oder unsigned sein kann. – AraK

+0

In der Tat! Vielen Dank! Jetzt werde ich nie erfahren, ob ich es einfach benutze. Es würde dir nichts ausmachen zu erklären, warum die Signiertheit in Char's eine Rolle spielt? Oder verweisen Sie auf einige Quellen? – tangrs

+0

Sie könnten denken, dass dies ein wenig zu generisch ein Link, aber es ist eigentlich ein sehr interessanter Artikel: http: //en.wikipedia.org/wiki/Integer_ (computer_science) –

7

Wenn char auf Ihrem System signiert ist, dann, wenn das obere Halbbyte von c f ist, ist c negativ und c% 16 ergibt ein negatives Ergebnis.

0

Ich weiß nicht, warum jemand *, /,% Operationen tut, während einfache bitweise Operationen solche Dinge tun können.

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

+0

Ganz im Gegenteil. Ich weiß nicht, warum jemand bitweise Operationen benutzen würde, wenn die normale menschliche Arithmetik das Ding genauso gut machen würde. – AnT

+0

Denn für Maschinen sind sie schneller als die "normale menschliche Arithmetik" – vrrathod

0

getchar und putchar Rückkehr und int s nehmen. Noch besser als diese verwenden sie den Wert der char Umwandlung in einen unsigned char, was bedeutet, dass für alle gültigen Zeichen putchar einen positiven Wert zurückgibt. Dies ist für Ihren Algorithmus erforderlich, da Sie % verwenden und Sie andernfalls auf das implementierungsdefinierte Verhalten angewiesen wären.

Wenn Sie den Wert getchar einem int zuweisen, können Sie testen, ob das Lesen aus irgendeinem Grund (nicht nur End-of-Stream) durch einen Vergleich mit EOF fehlgeschlagen ist. Mit feof ist dann nicht notwendig - es war vorher nicht ausreichend.

z.

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