Гетопт не включен? неявное объявление функции getopt

Я хотел использовать getopt, но это просто не сработает.

это дает мне

gcc -g -Wall -std=c99 -ftrapv -O2 -Werror -Wshadow -Wundef -save-temps -Werror-implicit-function-declaration   -c -o src/main.o src/main.c
src/main.c: In function ‘main’:
src/main.c:13:2: error: implicit declaration of function ‘getopt’ [-Werror=implicit-function-declaration]
src/main.c:23:14: error: ‘optarg’ undeclared (first use in this function)
src/main.c:23:14: note: each undeclared identifier is reported only once for each function it appears in
src/main.c:26:9: error: ‘optopt’ undeclared (first use in this function)
src/main.c:28:5: error: implicit declaration of function ‘isprint’ [-Werror=implicit-function-declaration]
src/main.c:36:5: error: implicit declaration of function ‘abort’ [-Werror=implicit-function-declaration]
src/main.c:36:5: error: incompatible implicit declaration of built-in function ‘abort’ [-Werror]
src/main.c:43:15: error: ‘optind’ undeclared (first use in this function)
cc1: all warnings being treated as errors
make: *** [src/main.o] Error 1

Вот исходник, если хотите (почти точная копия пасты из man-страницы getopt)

#include <stdio.h>
#include <unistd.h> // getopt
#include "myfn.h"

int main(int argc, char *argv[])
{

    int aflag = 0;
    int bflag = 0;
    char *cvalue = NULL;
    int c;

    while((c = getopt(argc, argv, "abc:")) != -1) {

        switch(c) {
            case 'a':
                aflag = 1;
                break;
            case 'b':
                bflag = 1;
                break;
            case 'c':
                cvalue = optarg;
                break;
            case '?':
                if (optopt == 'c')
                    fprintf (stderr, "Option -%c requires an argument.\n", optopt);
                else if (isprint(optopt))
                    fprintf (stderr, "Unknown option `-%c'.\n", optopt);
                else
                    fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);

                return 1;

            default:
                abort ();
        }

    }

    printf ("aflag = %d, bflag = %d, cvalue = %s\n", aflag, bflag, cvalue);

    for (int i = optind; i < argc; i++) {
        printf ("Non-option argument %s\n", argv[i]);
    }

    return 0;
}

Любые идеи, что я делаю неправильно?

Я на Linux, поэтому я предположил, что это должно работать так.


person MightyPork    schedule 22.03.2014    source источник
comment
просто то, что я использовал для отладки makefile, это не имеет значения.   -  person MightyPork    schedule 22.03.2014
comment
Почему вы хотите использовать флаг -implicit-function-declaration в этом случае.   -  person Mantosh Kumar    schedule 22.03.2014
comment
@tmp выдает ту же ошибку даже с -g -Wall -std=c99   -  person MightyPork    schedule 22.03.2014
comment
на какой системе вы работаете? Вы смотрели unistd.h? он содержит getopt?   -  person hek2mgl    schedule 22.03.2014
comment
Субунту 12.04. Конечно, некоторые пакеты могут отсутствовать, но я не могу понять, где должен быть getopt.   -  person MightyPork    schedule 22.03.2014
comment
Ну, я думаю (gcc -std=c99 main.c -o main) должно работать нормально, и, кажется, работает нормально. какая версия gcc работает на вашем компьютере?   -  person Mantosh Kumar    schedule 22.03.2014
comment
@MightyPork У меня это работает. какой дистрибутив Linux вы используете, также попробуйте сначала простой, например gcc prog.c -o prog, затем makefile   -  person Jayesh Bhoi    schedule 22.03.2014
comment
Это GCC 4.6.3. Я пробовал gcc main.c -o main -std=c99, но выдает ту же ошибку, что и раньше.   -  person MightyPork    schedule 22.03.2014
comment
@MightyPork пробовали с флагом -std=gnu99?   -  person Jayesh Bhoi    schedule 22.03.2014
comment
я сделал, это не сработало бы также. Теперь это решено благодаря @Guntram Blohm, спасибо, ребята, за предложения!   -  person MightyPork    schedule 22.03.2014


Ответы (5)


Попробуйте удалить файл -std=c99. Это предотвращает определение макросов POSIX в <features.h>, что не позволяет <unistd.h> включать <getopt.h>. Или включите getopt.h самостоятельно.

person Guntram Blohm    schedule 22.03.2014
comment
Я попробую это. Но я хочу объявлять переменные цикла внутри цикла, поэтому у меня c99. - person MightyPork; 22.03.2014
comment
Без проблем. Просто добавьте еще один #include <getopt.h> к вашему источнику. - person Guntram Blohm; 22.03.2014
comment
@MightyPork, вы можете попробовать -std=gnu99 вместо -std=c99. - person Jayesh Bhoi; 22.03.2014
comment
Все заработало, проблема действительно была в флаге std. Теперь успешно компилируем с -std=c99 и #include <getopt.h>. Но нужен ли мне unistd.h сейчас? (кстати, в чем разница ч/б c99 и gnu99?) - person MightyPork; 22.03.2014
comment
@GuntramBlohm: хороший улов +1. Кстати, я просто хотел знать, проверяли ли вы файл unistd.h и видели, как включен getopt.h, или вы знали об этом. - person Mantosh Kumar; 22.03.2014
comment
@tmp: я привык включать getopt.h, когда использую getopt (потому что, когда я использую getopt, я все равно использую версии gnu), и я не был уверен, что unistd.h вообще включает getopt.h. Итак, я поискал getopt в unistd.h, проверил контекст, проверил контекст __USE_POSIX2 в features.h, после чего стало ясно, что происходит. - person Guntram Blohm; 22.03.2014
comment
getopt — это расширение GNU для C. Если вы ограничитесь ISO C (-std=c99), оно будет недоступно. Используйте -std=gnu99, если можете, или включите getopt.h вручную (помните о проблемах с переносимостью, так как не все платформы предоставляют getopt.h) - person sleblanc; 03.08.2014
comment
getopt не является расширением GNU, а стандартизовано в POSIX. - person stefanct; 08.05.2021

Вы облако не удалить -std=c99. Вместо этого добавьте #define _POSIX_C_SOURCE 2 в начале.

person Zachary Wang    schedule 09.08.2016

Добавьте #include <getopt.h> среди включений.

person wandesky    schedule 08.09.2020
comment
Это предложение уже является частью принятого ответа - person Tim Randall; 08.09.2020

Нет абсолютно никакой необходимости изменять -std или напрямую включать getopt.h.

Если вы хотите использовать языковые функции C99 (или любые другие стандартизированные) вместе с функциями POSIX (например, getopt), правильно будет определить _POSIX_C_SOURCE в правильной версии (например, 200809L) перед включением соответствующих заголовков. Для получения дополнительной информации см. feature_test_macros(7).

person stefanct    schedule 08.05.2021

У меня была та же проблема, способ исправить это, скорее всего, вы компилируете с -std=c99, но вместо этого попробуйте -std=gnu99, и это должно сработать.

person Haider Khan    schedule 03.03.2021