Почему Atoi дает мне ошибку сегментации? - PullRequest
1 голос
/ 05 ноября 2010

У меня есть следующий фрагмент кода:

#include <stdio.h>

int main ( int argc, char *argv[] )
{
    int M, N;

    M = 1;
    N = 1;
    curr = 1;

    if ( argv[1][0] == '-' )
    {
        curr = 2;

        char *a = argv[1][1];
        char *b = argv[1][3];

        M = atoi(a);
        N = atoi(b);
    }

    printf("%d\n%d", M, N);
}

Итак, я передаю эту программу примерно так:

a.out -1,2

и вместо получения ожидаемого результата

1
2

У меня ошибка сегментации. Что дает?

Ответы [ 3 ]

8 голосов
/ 05 ноября 2010

Что компилируется?!

char argv * [] - массив указателей на символы.

char *a = argv[1][1] будет

  • Получить второй указатель на символ,так что теперь у вас есть char *.
  • Получить второй элемент в этом указателе, который будет символом.

Итак, теперь вы назначаете char для указателя char (что должно быть ошибкой компиляции).

Я могу только предположить, что вы хотели сказать char *a = &argv[1][1].Кстати, const-правильность тоже подойдет, поэтому const char *a = &argv[1][1].

Кстати, ваш код все еще очень небезопасен - вы даже не проверяете размер строки.Представьте, что делает &argv[1][3], если ваша строка содержит только два символа.

8 голосов
/ 05 ноября 2010

#include <stdlib.h> и это должно стать очевидным.

Для уточнения: вы передаете целое число в функцию, которая ожидает указатель, и компилятор не может предупредить вас, потому что вы забыли объявить функцию спрототип.Это является причиной сбоя.

Более того, вы просто неправильно используете atoi.atoi анализирует строки , а не отдельные символы.Если вы хотите, чтобы значение символа было цифрой, просто вычтите '0':

M = argv[1][1]-'0';
N = argv[1][3]-'0';

На практике вам также следует проверить, что символ на самом деле является цифрой.

Редактировать: Я не помню, чтобы char *a = argv[1][1]; находился в исходном сообщении (возможно, ранние правки не отображаются как правки?), Но любой здравомыслящий компилятор должен выдавать ошибку времени компиляции в этой строке.Целые числа неявным образом преобразуются в указатели на C. Если компилятор позволяет этому обойтись, то включение прототипа для atoi больше не поможет, поскольку ошибка типа произошла ранее.

2 голосов
/ 05 ноября 2010

atoi принимает строку, а не символ.

Кроме того, atoi в целом не очень хорош, поскольку в нем нет сообщений об ошибках. Вы должны исследовать strtol для большинства случаев.

...