2010-11-05 5 views
1

я следующий кусок кода:Почему atoi дает мне ошибку сегментации?

#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 

и вместо того, чтобы Ожидаемым результатом

Я получаю ошибку сегментации. Что дает?

+8

Какой сломанный компилятор вы используете? 'char * a = argv [1] [1];' должен давать ошибку компилятора ** **. C не имеет неявных преобразований из 'int' в типы указателей. –

ответ

7

Что собирает ?!

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

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

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

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

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

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

+1

Без файла заголовка по умолчанию предполагается, что функция существует (неявное объявление) как вызываемая и возвращает int. Это хороший аргумент для предупреждений, как об ошибках, так и о высоком предупреждении на вашем компиляторе. – Flexo

+2

Речь идет не о функции, а о присвоении 'char' символу' char * '. – EboMike

+0

Я предположил, что он имел в виду 'char * a = argv [1] + 1;' или '& (argv [1] [1]);' – Rup

8

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

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

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

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

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

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

+0

Я видел магические изменения на вопросы самостоятельно, без них они были помечены как отредактированные. Ужасный. – EboMike

2

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

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

Смежные вопросы