Вопрос по c – индекс массива имеет тип 'char'

3

У меня есть следующий код для чтения аргумента из командной строки. Если строка имеет длину 1 символ и цифру, я хочу использовать ее в качестве выходного значения. Компилятор выдает мне предупреждение во второй строке (нижний индекс массива имеет тип 'char'). Эта ошибка возникает во второй части после "&&".

<code>    if (args[1] != NULL) {
        if ((strlen(args[1]) == 1) && isdigit(*args[1]))
            exit(((int) args[1][0]));
        else
            exit(0);
    }
}
</code>

Кроме того, когда я использую другой компилятор, я получаю две ошибки на следующей строке (выход).

<code>builtin.c: In function 'builtin_command':
builtin.c:55: warning: implicit declaration of function 'exit'
builtin.c:55: warning: incompatible implicit declaration of built-in function 'exit'
</code>

Ваш Ответ

4   ответа
0

чт вы хотите дать код выхода, но, вероятно, вы хотитеargs[1][0] - '0' для десятичного значения, которое представляет символ, а не код символа.

Если вы сделаете это так, у вас будет побочный эффект, что тип этого выражения будетint и ты не увидишь предупреждение.

Дляexit вы, вероятно, забыли включить заголовочный файл.

Я на самом деле пытаюсь использовать фактический код символа, поэтому, если кто-то вводит выход 1 во ввод, то я хочу дать команду выхода (1) в моем коде. user994165
В этом случае тебе нужно вычесть'0' (обратите внимание на кавычки!), как предлагает Дженс, и как я предлагаю. Jonathan Leffler
1

что используемый вами компилятор имеет макрос для isdigit (а не функцию, у вас не было бы предупреждения, если бы это было так), которая использует аргумент в качестве индекса для массива. Вот почему isdigit принимает в качестве аргумента INT, а не символ.

Один из способов снять предупреждение, чтобы привести ваш char к int:

isdigit(*args[1]) => isdigit((int)(*args[1]))

Второе предупреждение означает, что вы хотите использовать функцию выхода, но она еще не определена. Это означает, что вы должны сделать необходимые # include.

#include <stdlib.h> 

является стандартом в c-библиотеке для использования функции выхода (int).

BTW, если этот код находится в вашей «основной» функции, вы не должны проверять «arg [1] == NULL», что может привести к ошибке сегментации, если пользователь не предоставил никаких аргументов в командной строке , Вы должны убедиться, что значение argc (параметр int) больше 1.

Кастинг вint удаляет предупреждение, но не опасность; только правильно привести кunsigned char а затем пусть это будет повышен доint. Jonathan Leffler
8

isdigit() macro принимает аргумент, представляющий собой целое число, являющееся либо значением EOF, либо значениемunsigned char.

ISO / IEC 9899: 1999 (стандарт C - старый), §7.4 Обработка символов<ctype.h>, №1:

Во всех случаях аргумент являетсяint, значение которого должно быть представлено какunsigned char или равно значению макроса EOF. Если аргумент имеет любое другое значение, поведение не определено.

На твоей платформе,char подписан, поэтому если у вас есть символ в диапазоне 0x80..0xFF, он будет рассматриваться как отрицательное целое число. Обычная реализацияisdigit() macros - использовать аргумент для индексации в массив битов флага. Поэтому, если вы передаете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(). Вам не нужно использовать это выражение, хотя это не навредит.

great, который позаботился о предупреждении «индекс массива имеет тип« char »», но я все еще получаю неявное объявление о выходе. У меня уже есть #include <stdlib.h> в заголовке. user994165
Не уверен, что случилось, но сейчас это работает. Благодарност user994165
Еслиexit() не объявлено в<stdlib.h>, тогда<stdlib.h> используемый заголовок поврежден. Вы уверены, что у вас нет пустого файла с именем<stdlib.h> таится где-то неожиданно? Используйтеgcc -H чтобы точно определить, какие заголовки включены. Jonathan Leffler
-1

Попробуй поменять

isdigit(*args[1])

К

isdigit(args[1][0])

Ваши другие ошибки связаны с тем, что вы не используете#include <stdlib.> который определяетexit функция.

@ cmh Я попробовал это и все еще получаю предупреждения. У меня был stdlib.h в шапке. user994165
Но еслиargs[1] этоchar*, не должен*args[1] бытьchar? Heinzi
@ user994165 попробуйте использоватьgcc -std=c99 как вВо cmh

Похожие вопросы