#c #cs50
Вопрос:
Я пробую себя get_string
в библиотеке CS50. get_string
Функция, по-видимому, вызывает ошибку ошибки сегментации. У вас есть какой-нибудь совет?
#include <cs50.h>
#include <stdio.h>
int main (void) {
string answer = get_string("What's your name? ");
printf("Hello, %s", answer);
}
Комментарии:
1. Я не думаю, что этот код может привести к ошибке сегментации
2. @EugeneSh. это вывод терминала: Macbook-Pro:Лязг MACBOOK$ сделать привет cc привет.c -o привет Macbook-Pro:Лязг MACBOOK$ ./Ошибка сегментации hello: 11
3. Да, это возможно, строка (которая есть
char*
) может быть НУЛЕВОЙ, Документация рекомендует специально проверять это cs50.readthedocs.io/libraries/cs50/c4. @JackWhite, найденный в документах «Возвращает строку чтения в виде строки. Если пользователь вводит только окончание строки, возвращает «», а не NULL. Возвращает значение NULL при ошибке или вообще без ввода (т. Е. Просто EOF).» . Звучит маловероятно, если только ОП намеренно не снабжает его EOF…Я все еще думаю, что ОП на самом деле не запускает этот код.
5. Должно быть в том же каталоге
make
, в котором вы работаете
Ответ №1:
Ладно, после некоторых поисков я думаю, что нашел виновника. И, по-видимому, это не то место, где мы искали.
Mac OS X , по-видимому, имеет встроенный символ с именем get_string
, поэтому он скомпилирован без библиотеки и продолжает сбоить.
К этой проблеме может быть несколько подходов
Скомпилируйте cs50.c
в свой двоичный файл
Этот метод был упомянут здесь. Я не тестировал его, но, как сообщается, он работает.
Скомпилируйте свой код следующим образом:
clang -ggdb3 -O0 -std=c99 hello.c ../../../github.com/cs50/lib50-c/src/cs50.c -o hello
где ../../../github.com/cs50/lib50-c/src/cs50.c
путь к файлу cs50.c
, который находится в подкаталоге src
cs50
исходного кода библиотеки — если на вашем компьютере он отличается, пожалуйста, используйте правильный путь.
Вы также можете просто скопировать cs50.c
файл в каталог с hello.c
помощью и просто указать cs50.c
путь без
Пожалуйста, обратите внимание, что вы должны указать этот файл после вашего, иначе он не будет работать!
На самом деле, в таком случае этого должно быть достаточно:
cc hello.c cs50.c -std=c99 -o hello
С этого момента вам нужно будет включать cs50.c
после себя каждый раз, когда вы будете компилировать свой код.
Переименуйте функцию
Поскольку у меня нет Mac, я не могу ничего протестировать, поэтому перечислю единственный способ, который наверняка сработает — переименовать функцию get_string
в get_string2
. Это не очень хорошее решение, но это все, что я могу вам сейчас дать.
Пожалуйста, используйте это только в том случае, если первый подход не работает.
- перейдите в каталог, из которого вы установили cs50
- удалите его, выполнив команду
sudo make uninstall
- откройте файл
cs50.h
из подкаталогаsrc
в любом текстовом редакторе - найдите и замените все вхождения
get_string
сget_string2
(у меня был один в строке 108 и два в строке 109) - сохраните и закройте файл
- откройте файл
cs50.c
из подкаталогаsrc
в любом текстовом редакторе - найдите и замените все вхождения
get_string
сget_string2
(их очень много) - сохраните и закройте файл
- вернитесь в исходный каталог сборки cs50 и выполните команды:
make clean
make
sudo make install
- перейдите в каталог с
hello.c
- отредактируйте
hello.c
и заменитеget_string
наget_string2
- скомпилируйте
cc hello.c -lcs50 -o hello
и запустите с помощью./hello
Вам также может потребоваться выполнить следующие команды перед компиляцией и выполнением:
export LIBRARY_PATH=/usr/local/lib
export C_INCLUDE_PATH=/usr/local/include
export LD_LIBRARY_PATH=/usr/local/lib
- С этого момента вам нужно будет менять каждое использование
get_string
в вашем коде наget_string2
- не забудьте изменить обратно при отправке кода.
В качестве альтернативы вы могли бы поместить что-то подобное в начале своих программ:
#ifndef get_string2
#define get_string2 get_string
#endif
…это означает, что для всех остальных, кто запускает ваш код (и не имеет макроса get_string2
), это будет то get_string2
же get_string
самое, что и — поэтому ваш код будет работать как с измененной, так и с неизмененной библиотекой.
Опять же, это явно не лучший способ сделать это, но, поскольку я не могу его проверить, это лучшее, что я мог придумать. Извините.
Если кто — то другой предложит лучший способ-это было бы здорово
Комментарии:
1.
-std=c99
должно предотвратить определение любых нестандартных символов-если это действительно проблема, о ней следует сообщить как об ошибке компилятора