Объяснение ошибки сегментации CS50 Caesar

#c #segmentation-fault #cs50 #argv

#c #ошибка сегментации #cs50 #argv

Вопрос:

Я могу скомпилировать этот код без проблем, идея прямо сейчас состоит в том, чтобы просто проверить, что я могу успешно ввести ключ шифрования (аргумент командной строки) без каких-либо проблем, прежде чем двигаться дальше. Мне не повезло выяснить, почему мой код всегда возвращает ошибку сегментации, затем я увидел подсказку поставить ‘*’ перед argv[1] в 4-й строке, и это, кажется, решает все мои проблемы. Может кто-нибудь, пожалуйста, объяснить мне, почему это?

 int main(int argc, string argv[]) // command line argument for the cipher key
{
    int key;
    if (argc == 2 amp;amp; isdigit(*argv[1])) //the line in question
    {
        key = atoi(argv[1]); // convert the digit string into an integer
    }
    else
    {
        printf("Usage:./caeser keyn");
        return 1;
    }
printf ("%in",key);
}
  

Комментарии:

1. Вы уверены, что это argv так string , а не char * нет? Это C не C , верно?

2. @eldesgraciado вопрос помечен CS50 . Определен string тип, который является char* .

3. @eldesgraciado Этот вопрос — просто еще один пример того, как string мерзость CS50 привела в замешательство другого нового программиста. Использование char * типа для ссылки на массив char значений, который заканчивается '' значением, является фундаментальной концепцией в C, которую CS50 запутывает своей ошибочной «строкой» typedef . Это все равно что пытаться научить кого-то писать по буквам, а затем говорить: «Нет, вам действительно не нужно знать, что такое вещи, называемые «буквами»». Или «Цифры? Вам не нужно знать цифры, чтобы считать!»

4. @AndrewHenle А typedef , да? вау, это абсолютно аберрантно . Как они могут обучать, используя эти методы?

Ответ №1:

затем я увидел подсказку поставить ‘*’ перед argv[1] в 4-й строке, и это, кажется, решает все мои проблемы. Может кто-нибудь, пожалуйста, объяснить мне, почему это?

Это означает, что до того, как вы увидели этот совет, он выглядел следующим образом:

 isdigit(argv[1])
  

Здесь вы смешиваете типы.

argv является массивом char* . Это означает, что argv[1] имеет тип char* . Но isdigit ожидает аргумент типа int . За это вы должны получить некоторое предупреждение компилятора. Функция ожидает получить значение, которое находится в диапазоне char или EOF . Передача указателя, скорее всего, приведет к выходу некоторого значения за пределы диапазона.

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