функция Atoi в C не работает должным образом - PullRequest
4 голосов
/ 16 октября 2011

Может кто-нибудь объяснить, почему функция atoi не работает с nuber, который имеет более 9 цифр.
Например:

Я ввел 123456789, программа говорит 123456789, но когда я ввел 12345678901, программа скажет -519403114 ... Спасибо за помощь.

int main ()
{
    int i;
    char szinput [256];
    printf ("Enter a Card Number:");
    fgets(szinput,256,stdin);
    i=atoi(szinput);
    printf("%d\n",i);
    getch();
    return 0;
}

Ответы [ 3 ]

9 голосов
/ 16 октября 2011

Не используйте atoi() или любую из функций atoi*(), если вы заботитесь об обработке ошибок. Эти функции не позволяют обнаруживать ошибки; ни atoi(99999999999999999999), ни atoi("foo") не может сказать вам, что возникла проблема. (Я думаю, что один или оба из этих случаев на самом деле имеют неопределенное поведение, но я должен проверить, чтобы убедиться.)

Функции strto*() немного сложны в использовании, но они могут надежно сказать вам, представляет ли строка действительное число, находится ли она в диапазоне и каково ее значение. (Вы должны иметь дело с errno, чтобы получить полную проверку.)

Если вы просто хотите получить значение типа int, вы можете использовать strtol() (который после проверки ошибок даст вам результат long) и преобразовать его в int после также , проверяя, что результат находится в представимом диапазоне int (см. INT_MIN и INT_MAX в <limits.h>). strtoul() дает вам unsigned long результат. strtoll() и strtoull () для long long и unsigned long long соответственно; они новы в C99, и ваша реализация компилятора может не поддерживать их (хотя, вероятно, большинство реализаций сторонних разработчиков).

6 голосов
/ 16 октября 2011

Поскольку вы переполняете int с таким большим значением.

Более того, atoi устарело и небезопасно для многих платформ, поэтому вам лучше отказаться от него в пользу strto(l|ll|ul|ull).

Попробуйте вместо этого использовать strtoull.Поскольку unsigned long long является 64-битным типом на большинстве современных платформ, вы сможете преобразовать число размером 2 ^ 64 (18446744073709551616).

Чтобы напечатать unsigned long long, используйтеспецификатор формата %llu.

0 голосов
/ 14 марта 2012

если вы пишете win32 приложение, то вы можете использовать реализацию atoi для Windows, подробности смотрите на странице ниже.

http://msdn.microsoft.com/en-us/library/czcad93k%28v=vs.80%29.aspx

...