我实现了一种将给定字符数组转换为十进制整数的方法。该方法将从数组中取出每个字符,计算其十进制值,然后将其乘以10 ^ n,其中n在每次迭代时都会递增。
因此,例如数组4711将像这样转换。 1 * 10 ^ 0 + 1 * 10 ^ 1 + 7 * 10 ^ 2 + 4 * 10 ^ 3 = 4711作为十进制值。
我现在的问题是如何扩展功能,以便stringTOint方法还能够处理八进制和六进制值,例如023或0x1A。
/** Converts the given array of characters into a decimal integer */
int stringTOint(char str[]) {
int i, flag, offset, n,base;
flag = 0;
base = 10;
char c = '0';
/*if the first char in the array is '-', the minus flag gets set */
if (str[0] == '-') {
flag = -1;
}
if (flag == -1) {
offset = 1;
} else {
offset = 0;
}
if(offset == 0) {
if (str[0] == '0' && (str[1] != 'x' && str[1] != 'X') ) {
base = 8; // Octal
} else if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
base = 16; // Hexadecimal
offset = offset + 2;
}
}else if(offset == 1) {
if (str[1] == '0' && (str[2] != 'x' && str[2] != 'X') ) {
base = 8; // Octal
} else if (str[1] == '0' && (str[2] == 'x' || str[2] == 'X')) {
base = 16; // Hexadecimal
offset = offset + 2;
}
}
n = 0;
/*Loop runs until terminating NULL gets found in array */
for (i = offset; str[i] != '\0'; i++) {
n = n * base + str[i] - c;
}
/*value becomes negative if the negative flag was set */
if (flag == -1) {
n = -n;
}
/* n gets returned */
return n;
}
答案 0 :(得分:0)
您不处理十六进制值从A
到F
的情况。
for (i = offset; str[i] != '\0'; i++) {
int value = (str[i] > ='A' && stri[i]<='F')? (str[i]-'A'+10):(str[i]-'0');
n = n * base + value;
}
也就是说,如果char是A
到F
,只需从A
中减去char
并加上10
就可以得到十六进制表示形式。
注意:您需要使用%X
或%x
以十六进制表示法打印。
答案 1 :(得分:0)
另一种方法是使用有效数字数组。使用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)))) {
答案 2 :(得分:-1)
我的想法是检查数组中的当前char是否为十进制(因此为0-9),或者是否为字母(因此为AF),然后将-'0'更改为-'A',然后如果是字母,则为十进制数字。
for (i = offset; str[i] != '\0'; i++) {
if(str[i]==/*ABCDEF*/) {
c = 'A';
} else if( str[i]==/*0123456789*/) {
c = '0';
}
n = n * base + str[i] - c;
}
但是我不确定如何检查当前字符,因为它只需要是其中的一个,并且应该有一个更好的方法来执行9 if语句并将其与逻辑或组合。