2010-02-07 9 views
6

Muy bien, he preparado un código para invertir los caracteres hexadecimales como parte de un ejercicio divertido que inventé.¿Qué hay de malo con mi algoritmo?

Aquí es lo que tengo en este momento:

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

Funciona bien para la mayoría de los valores. Por ejemplo, 0xA0 se convierte en 0x0A, etc. ...

Sin embargo, no está funcionando bien con valores que comienzan con 'F'.

0xf1 convierte 0x10
0xFF se convierte en 0xF0
etc ...

Puede alguien me punto en la dirección correcta?

+4

necesita espacio para que sus matemáticas funcionen. usa int para a y b en lugar de char. O cambie a usar operaciones bit a bit (>><< & y |) en lugar de operaciones matemáticas. –

+0

@KennyTM: probablemente quiera decir 'putchar (cc >> 4 | (cc & 0xf) << 4);' – mjv

+1

Como nota adicional: no hay necesidad de restar 'a' de' c' antes de dividir por 16. 'b = c/16' le dará exactamente el mismo resultado. Así es como funciona la división de enteros en C. – AnT

Respuesta

5

Está utilizando un tipo de datos firmado (en su máquina). Cambie a unsigned y debería funcionar correctamente.

+2

Tiene la solución, pero tenga en cuenta que 'char' se puede firmar o no, dependiendo de la implementación. – AraK

+0

¡De hecho! ¡Gracias! Ahora, ya que nunca aprenderé si simplemente lo uso. ¿No le importaría explicar por qué lo firmado es importante en Char? ¿O señalar algunas fuentes? – tangrs

+0

Usted podría pensar que este es un enlace demasiado genérico, pero en realidad es un artículo muy interesante: http: //en.wikipedia.org/wiki/Integer_ (computer_science) –

7

Si char está registrado en su sistema, entonces cuando el nibble superior de c es f, c es negativo, y c% 16 dará un resultado negativo.

0

No sé por qué alguien está haciendo operaciones *, /,%, mientras que las operaciones simples en modo bit pueden hacer tales cosas.

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

+0

Todo lo contrario. No sé por qué alguien usaría operaciones bit a bit en las que la aritmética humana normal también lo haría. – AnT

+0

Porque para las máquinas son más rápidas que las "aritméticas humanas normales" – vrrathod

0

getchar y putchar retorno y tomar int s. Incluso mejor que esto, usan el valor de la conversión char a unsigned char, lo que significa que para todos los caracteres válidos putchar devolverá un valor positivo. Esto es necesario para su algoritmo cuando usa % y de otro modo necesitaría confiar en el comportamiento definido por la implementación.

Si asigna el valor de getchar a int, entonces puede probar si la lectura falló por algún motivo (no solo al final de la secuencia) comparando con EOF. No es necesario utilizar feof, no era suficiente antes.

E.g.

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