#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
, и это работает так, как должно.