Проблема заключается в том, что isdigit()
макрос принимает аргумент, который является целым числом, либо значение EOF или значение из unsigned char
.
ИСО/МЭК 9899: 1999 (C Стандарт – старые), §7.4 обработки <ctype.h>
, ¶1 Характер:
Во всех случаях аргумент является int
, значение которого должно быть представим в виде a unsigned char
или должен быть равен значению макроса EOF.Если аргумент имеет любое другое значение, поведение не определено.
На вашей платформе, char
подписан, так что если у вас есть символ в диапазоне 0x80..0xFF, он будет рассматриваться как отрицательное число. Обычная реализация макросов isdigit()
заключается в использовании аргумента для индексации в массив бит флагов. Поэтому, если вы передадите char
из диапазона 0x80..0xFF, вы будете индексировать до начала массива, что приведет к неопределенному поведению.
#define isdigit(x) (_CharType[(x)+1]&_Digit)
Вы можете безопасно использовать isdigit()
в одном из двух способов:
int c = getchar();
if (isdigit(c))
...
или:
if (isdigit((unsigned char)*args[1]))
...
В последнем случае, вы знаете, что значение не будет EOF. Обратите внимание, что это не в порядке:
int c = *args[1];
if (isdigit(c)) // Undefined behaviour if *args[1] in range 0x80..0xFF
...
Предупреждение о «неявном определении функции выхода» означает, что вы не включили <stdlib.h>
, но вы должны сделать это.
Вы также можете заметить, что если пользователь дает вам 2 в качестве первого символа первого аргумента, статус выхода будет равен 50, а не 2, так как '2'
(обычно в ASCII и UTF-8 и 8859- 1 и т. Д.) Код символа 50 ('0'
- 48 и т. Д.). Вы получите 2
(без кавычек), используя *args[1] - '0'
в качестве аргумента для exit()
. Вам не нужно прикладывать это выражение, хотя это не навредит.
отлично, что позаботился о том, что «индекс массива имеет тип« char », но я все равно получаю неявное объявление о выходе. У меня уже есть #include в моем заголовке. –
user994165
Если 'exit()' не объявлен в '', то заголовок '', который используется, не работает. Уверены ли вы, что у вас нет пустого файла с именем '' где-то неожиданным? Используйте 'gcc -H', чтобы точно указать, какие заголовки включены. –
Не знаете, что произошло, но теперь оно работает. благодаря – user994165