Преобразовать строку в int с отрицательными числами - PullRequest
0 голосов
/ 11 ноября 2018

Мне нужно написать функцию на 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;
}

Моя проблема в том, что мне нужно, чтобы он также работал с отрицательными числами / массивами символов, начинающимися с '-'.

Я знаю, что должен проверить, является ли первый символ '-', но я застрял после этого.

Я знаю, что '-' - это 45-й символ таблицы ASCII, но я почему-то не могу придумать, как заставить его работать.

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Я уже сделал это успешно (с положительным результатом) с этим кодом:

Хорошо. Важное понимание заключается в том, чтобы развивать успех.

Поскольку 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(), но я хотел подчеркнуть, что повторное использование кода . Это делает продуктивного кодера.

0 голосов
/ 11 ноября 2018

Еще одна переменная может быть добавлена ​​для распознавания знака.Затем умножьте на переменную знака.
Необходимо добавить проверку, чтобы подтвердить, что обрабатываются только цифры.Если вход был 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;
}
...