c 将字符串更改为 int

c-changing string to int

我正在尝试将一串字符更改为数字。 比如字符串'5','3','9'变成539。 我所做的是:

for (j = 0; j < len_of_str; j++)
     num = num + ((str[j] - 48) * (10 ^ (len_of_str - j)))    
printf("%d", num);

num 是包含数字的数字 int 负 48 是将 ASCII 中的值更改为类似于实数的数字。 (10 ^ (len_of_str - j)) 是将值更改为数百、数千等...

几个问题:

首先,^ 不是 C 中的求幂运算符 - 它是按位异或运算符。你得到的不是 10N,而是 10 XOR N,这不是你想要的。 C 没有求幂运算符(对于定义了 110 亿个运算符的语言来说具有讽刺意味,但你去吧)——你需要使用库函数 pow 来代替。或者您可以避免整个问题并改为这样做:

num = 0;
for ( j = 0; j < len_of_str; j++ )
{
  num *= 10;
  num += str[j] - 48;
}

其次,str[j]-48 假定 ASCII 编码。为了使它更通用一点,请改用 str[j] - '0' (在大多数编码中,数字字符是连续的, 所以 '9' - '0' 应该 等于 9)。

最后,您有没有使用 atoistrtol 等内置库函数之一的原因?

num = (int) strtol( str, NULL, 0 );
printf( "num = %d\n", num );

正如上面的评论所指出的,^ 实际上并没有计算幂,而是进行了按位异或(参见 wikipedia)。例如对于 0101 ^ 0111 == 0010,因为 XOR 只会将位设置为输入在该位上不同的位。

要计算 c 中某项的 10 次方,请使用 <math.h> 中的 pow(double x, double y)。有关详细信息,请参阅 this post

将数字序列转换为整数是将数字(整数或实数)解析为二进制整数或双精度值的更一般情况的特例。

一种方法是使用模式来描述数字,您可以迭代地或递归地描述该模式,如下所示,

An integer_string is composed of:
    and optional '+' or '-' (sign)
    follwed by a digit_sequence
a digit_sequence is composed of:
    digit ('0', '1', '2', '3', ..., '9')
    followed by an optional (recursive) digit_sequence

这可以使用 Backus-Naur 形式主义写成,

integer_string := { '+' | '-' } digit_sequence
digit_sequence := digit { digit_sequence }
digit := [ '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ]

如果你愿意,你可以扩展上面的内容以识别实数,

real_number := integer_string { '.' { digit_sequence } }
               { [ 'e' | 'E' ] integer_string }

虽然上面的不是很正确,因为它强制在小数点前加一个数字(修复留作 reader 的练习)。

一旦有了 Backus-Naur 形式主义,就很容易识别构成模式的符号,以及实际转换为整数的语义动作

long int
atol_self(char* str)
{
    if(!str) return(0);
    //accumulator for value
    long int accum=0; //nothing yet
    //index through the string
    int ndx=0;
    //handle the optional sign
    int sign=1;
    if ( str[ndx=0] == '+' ) { sign=1; ndx+=1; }
    else if ( str[ndx=0] == '+' ) { sign=1; ndx+=1; }
    for( ; str[ndx] && isdigit(str[ndx]); ) {
        int digval = str[ndx] - '0';
        accum = accum*10 + digval;
        ++ndx;
    }
    return(accum*sign);
}