2016-07-16 6 views
2

Ich muss eine hexadezimale Zahl mit acht Ziffern in C lesen und ich muss es validieren. Wenn es weniger als acht Ziffern hat, fülle es mit "0". Wenn es mehr als acht Ziffern hat, drucken Sie eine Nachricht wie "Bitte geben Sie eine gültige Nummer ein".Lesen Sie eine Hexadezimalzahl und validieren Sie ihre Anzahl an Ziffern in C

ich so etwas wie das tue:

unsigned int number; 

printf("\nIntroduzca un número: "); 
scanf("%08x", &number); 

Aber mit „% 08x“ kann ich mit „0“ füllen, aber ich kann nicht wissen, ob die eingelegte Zahl mehr als acht Ziffern hat und drucken die Fehlermeldung.

Ich dachte, es als String lesen, aber später muss ich Bit-Operationen auf es tun und das Ergebnis in hexadezimalen und binären drucken, so dass ich nicht weiß, ob es eine gute Idee ist, die Zahlen als Zeichenfolgen zu lesen.

Wie kann ich dieses Problem lösen?

+1

Ich würde stattdessen eine Zeichenfolge lesen, überprüfen Sie ihre Länge, dann verwenden Sie 'strtol' mit Basis 16, um es in hex konvertieren. Hinweis: 'strtol' erlaubt einen optionalen vorangestellten' 0x', also sollten Sie sicherstellen, dass der String nicht damit beginnt. Sie können auch überprüfen, dass die Zahl nicht größer als "ffffffff" ist. – Evert

+0

Verwenden Sie 'sprintf', um die Zahl (zurück) in einen String zu konvertieren, füllen Sie ihn bei Bedarf mit Nullen auf. – Evert

+0

'* printf' verwendet'% 0nx', wobei n die Breite (ungleich Null) ist, um Pad mit Nullen anstelle von Leerzeichen zu bezeichnen, aber '* scanf' hat keine spezielle Bedeutung für'% 0nx'; '% 08x' bedeutet Parse _up to_ 8 Zeichen in Hex als' unsigned int' genauso wie '% 8x'. (Beachten Sie auch, dass 'unsigned int' auf einigen Systemen nicht 32 Bit hat, aber Sie wahrscheinlich nicht darauf stoßen werden.) –

Antwort

2

Selten ist scanf() die beste Wahl für Benutzereingaben. Besser, fgets() zu verwenden, um eine Zeile und dann zusätzlichen Code zu lesen, um die Zeichenfolge zu analysieren.

char buf[100]; 
while (fgets(buf, sizeof buf, stdin)) { 
    // code read the text input into a string, now do something with it. 

-Code sucht acht hexadezimale Ziffern und OP ist auf dem richtigen Weg mit scanf("%08x".... 0 wird hier nicht benötigt, nur 8 wird tun, um die Eingabe auf 8 Ziffern zu begrenzen. Verwenden Sie " ", um alle optionalen Leerzeichen zu überspringen. Verwenden Sie "%n", um die Anzahl der analysierten Zeichen aufzuzeichnen.

unsigned number = 0; 
    int n = 0; 
    // If any length (up to 8) hex text was found ... 
    // ... and test if `buf[n]` is the end of the string or maybe that 9 digit? 
    if (sscanf(buf, "%8x %n", &number, &n) == 1) && buf[n] == '\0') { 
    printf("Success :%08x\n", number); 
    } else { 
    fprintf(stderr, "please insert a valid number\n"); 
    } 
} 

Wenn Codetext, um sicherzustellen, muss enthalten nicht ein führendes wie "0x123", ist mehr Arbeit erforderlich. Verschiedene Ansätze.

Verkleben Sie mit *scanf() Spezifizierer, verwenden Sie "%*[abcdefABCDEF]", um einen String nach Hex-Ziffern zu scannen. Die * bedeutet nicht speichern, nur scannen.

int n = 0; 
    // If any length (up to 8) hex text was found ... 
    // ... and test if `buf[n]` is the end of the string or maybe that 9 digit? 
    sscanf(buf, "%*8[abcdefABCDEF] %n", &n); 
    if (n > 0 && buf[n] == '\0') { 
    unsigned long number = strtoul(buf, NULL, 16); 
    printf("Success :%08lx\n", number); 
    } else { 
    fprintf(stderr, "please insert a valid number\n"); 
    } 
} 

Eine klug Weise ist *scanf() alle zusammen zu vermeiden und ein "0x" auf den String prepend analysiert und strtol() nur für die Analyse verwenden werden.

char buf[100]; 
while (fgets(&buf[2], sizeof buf - 2, stdin)) { 
    char *endptr; 
    buf[0] = '0'; 
    buf[1] = 'x'; 
    unsigned long number = strtoul(buf, &endptr, 16); 
    int length = (int) (endptr - buf); 
    if (length < 3 || length > (2 + 8) || *endptr != '\n') { 
    fprintf(stderr, "please insert a valid number\n"); 
    } else { 
    printf("Success :%08lx\n", number); 
    } 
} 
+1

Der _clever_ Trick im letzten Teil benutzt' strtoul (..., ..., 16) 'und 'sscanf (...,"% x ", ...)' erlaubt eine optionale vorangestellte "0x" '. Indem der String mit "0x" vorangestellt wird und dann diese Zeichenfolge analysiert wird, werden Benutzereingaben wie "0x123" als "0x0x123" analysiert. Dann wäre die stoppende Analyseposition nicht das Ende der Zeichenfolge. – chux

+0

Sie waren richtig, ich entschied mich, fgets() zu verwenden, um die Zeile zu lesen und zu validieren, und strtol(), um sie zu analysieren. –

2

Lesen Sie es als Zeichenfolge. Überprüfen Sie die ersten 2 Bytes, um sicherzustellen, dass sie keine 0x an den Anfang hinzugefügt haben. Verwenden Sie strlen, um die Länge zu überprüfen. Dann

als @Evert sagte, verwenden strtol es zu einem Hex-Wert zu konvertieren, mit Hilfe der Basis 16. Überprüfen Sie den Rückgabewert von strtol Erfolg oder Misserfolg überprüfen - gültig Hex-Nummer eingegeben oder nicht.

Verwandte Themen