将字符串转换为带负数的整数

时间:2018-11-11 13:15:08

标签: c char int

我需要用C编写一个将字符串(由char *指向的数据)转换为int的函数。我已经使用以下代码成功完成了此操作:

int charTOint(char * c) {
    char p = *c;
    int ergebnis = 0;

    while (p) {
        ergebnis = ergebnis * 10 + (p - '0');
        c++;
        p = *c;
    }

    return ergebnis;
}

我现在的问题是,我还需要它也可以使用以'-'开头的负数/字符数组。

我知道我必须检查第一个字符是否为'-',但是在那之后我陷入了困境。

我知道'-'是ASCII表的第45个字符,但是我不知怎么想出一种使其工作的方式。

2 个答案:

答案 0 :(得分:2)

  

我已经使用以下代码成功(肯定)地完成了此操作:

好。一个重要的见识就是要以成功为基础。

由于int charTOint(char * c) {可以很好地处理正值,因此可以使用unsigned重新编写。由于UINT_MAX通常大于INT_MAX,因此我们获得了更大的射程。

unsigned charTOunsigned(const char * c) {
    char p = *c;
    unsigned ergebnis = 0;
    while (p) {
        ergebnis = ergebnis * 10 + (p - '0');
        c++;
        p = *c;
    }
    return ergebnis;
}
  

我还需要它与以'-'开头的负数/字符数组一起工作。

现在拥有charTOunsigned()的武装,使用现有良好代码的变体来重新制作满足附加目标的int charTOint()。通常使用charTOunsigned()的额外正数范围,int charTOint()将很容易处理转换为INT_MIN的字符串。

int charTOint(const char * c) {
  return (*c == '-') ? -charTOunsigned(c+ 1) : charTOunsigned(c);
}

当然可以编写一个独立的charTOint(),但我想强调代码重用。这样就可以生产出高效的编码器。

答案 1 :(得分:1)

可以添加另一个变量来识别符号。然后乘以符号变量。
应该添加检查以确认只处理数字。如果输入是123abc,则将在123

之后停止
int charTOint(char * c) {
    char p = *c;
    int ergebnis = 0;
    int sign = 1;

    if ( '-' == *c || '+' == *c) {
        if ( '-' == *c) {
            sign = -1;
        }
        c++;
    }
    while (*c) {
        p = *c - '0';
        if ( 0 <= p && 9 >= p) {// digit 0 to 9
            ergebnis = ergebnis * 10 + p;
            c++;
        }
        else {
            break;//not a digit
        }
    }

    return ergebnis * sign;
}

编辑3:

#include <stdio.h>
#include <string.h>
#include <limits.h>

int charTOint(char *c, int *number) {
    char p = *c;
    int sign = 1;
    int divmax = INT_MAX / 10;
    int divmin = INT_MIN / 10;

    *number = 0;
    while ( ' ' == *c || '\t' == *c) {
        c++;//skip leading spaces tabs
    }
    if ( '-' == *c || '+' == *c) {
        if ( '-' == *c) {
            sign = -1;
        }
        c++;
    }
    while (*c) {
        p = *c - '0';
        if ( 0 <= p && 9 >= p) {// digit 0 to 9
            if ( *number <= divmax && *number * 10 <= INT_MAX - p) {
                *number = *number * 10 + p;
                c++;
            }
            else {
                if ( sign < 0 && *number * sign >= divmin && *number * sign * 10 >= INT_MIN + p) {
                    *number = *number * sign * 10 - p;
                    return 1;
                }
                fprintf ( stderr, "\n\t\tOVERFLOW\n\n");
                *number = 0;
                return 0;
            }
        }
        else {
            *number = 0;
            return 0;//not a digit
        }
    }

    *number = *number * sign;
    return 1;
}

int main ( void) {
    char text[100] = "";
    int value = 0;

    do {
        printf ( "enter an integer or enter done\n");
        if ( fgets ( text, sizeof text, stdin)) {
            text[strcspn ( text, "\n")] = 0;
            if ( charTOint ( text, &value)) {
                printf ( "value = %d\n", value);
            }
            else {
                printf ( "input [%s]\n", text);
            }
        }
        else {
            fprintf ( stderr, "fgets EOF\n");
            return 0;
        }
    } while ( strcmp ( text, "done"));
    return 0;
}