Другой подход - иметь массив допустимых цифр.Используйте strchr
для проверки правильности цифры.Если допустимо, разница между указателями - это значение, которое нужно добавить без необходимости вычитать символьные константы.
#include <stdio.h>
#include <string.h>
int stringTOint(char *str, int *number) {
char *digits = "0123456789";//pointer to string literal
char *valid = NULL;
char add = 0;
int sign = 1;
int base = 10;
*number = 0;
while ( ' ' == *str || '\t' == *str) {
str++;//skip leading spaces tabs
}
if ( '-' == *str || '+' == *str) {
if ( '-' == *str) {
sign = -1;
}
str++;
}
if ( '0' == *str) {
digits = "01234567";//assign pointer to different string literal
base = 8;
str++;
if ( 'x' == *str) {//lowercase
digits = "0123456789abcdef";
base = 16;
str++;
}
if ( 'X' == *str && '0' == *(str - 1)) {//uppercase
digits = "0123456789ABCDEF";
base = 16;
str++;
}
}
while (*str) {//not at terminating zero
if ( ( valid = strchr ( digits, *str))) {//is a valid digit
add = valid - digits;//value to add is difference between pointers
*number = *number * base + add;
str++;
}
else {
*number = 0;
return 0;//not a valid digit
}
}
*number = *number * sign;
return 1;
}
int main ( void) {
char text[100] = "";
int value = 0;
do {
printf ( "enter an integer\n\t(leading 0 octal or leading 0x hexal)\n\tor enter done\n");
if ( fgets ( text, sizeof text, stdin)) {
if ( '\n' == text[0]) {
break;//exit on empty line
}
text[strcspn ( text, "\n")] = 0;//remove newline
if ( stringTOint ( text, &value)) {
printf ( "decimal value = %d\n", value);
}
else {
printf ( "\n\tinput problem [%s]\n\n", text);
}
}
else {
fprintf ( stderr, "fgets EOF\n");
return 0;
}
} while ( strcmp ( text, "done"));//exit if input is done
return 0;
}
Добавить
if ( 'b' == *str) {
digits = "01";//assign pointer to different string literal
base = 2;
str++;
}
перед
while (*str) {//not at terminating zero
идвоичное значение может обрабатываться с использованием входных данных, таких как b1101
. Чтобы разрешить сочетание верхнего и нижнего регистра в шестнадцатеричных значениях, удалите весь блок if
для верхнего регистра, включите ctype.h
и измените
if ( 'x' == *str) {
до
if ( 'x' == *str || 'X' == *str) {
и изменить
if ( ( valid = strchr ( digits, *str))) {
на
if ( ( valid = strchr ( digits, tolower ( *str)))) {