LINUX.ORG.RU

как отличить имя файла от аргумента опции при использовании getopt()?


0

1

Собственно сабж. Для получения аргумента опции юзается optarg, а как аргумент опции отличить от имени файла? Извините, если вопрос уж совсем идиотский/дебильный, просто хочется знать, как это реализовать. Заранее спасибо всем, кто поможет.

★★★

Ответ на: комментарий от Deleted

Я читал подобное на сайте IBM. Прикол в том, что имя файла не является ни опцией ни аргументом опции. Ещё идеи?

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

у тебя в main должны передаваться int argc, char * const argv[], перед тем как отдавать в getopt возьми из argv нулевой элемент, это и будет имя файла.

Deleted
()
Ответ на: комментарий от Dorif

verbatim copy from getopt(3)

int bflag, ch, fd;
char *filename;

bflag = 0;
while ((ch = getopt(argc, argv, "bf:")) != -1) {
        switch (ch) {
                case 'b':
                        bflag = 1;
                        break;
                case 'f':
                        if ((fd = open(optarg, O_RDONLY, 0)) == -1)
                                err(1, "%s", optarg);
                        break;
                default:
                        usage();
                        /* NOTREACHED */
                }
        }

argc -= optind;
argv += optind;

if (argc > 0)
        filename = *argv;

/* and so on */

оно?

beastie ★★★★★
()
Ответ на: комментарий от Deleted

Мне нужно не имя файла запускаемой проги. Проге передаётся имя какого- либо файла для совершения с ним каких- либо действий. Имя этого файла не является ни опцией, ни аргументом.

Dorif ★★★
() автор топика
Ответ на: verbatim copy from getopt(3) от beastie

Нет. Пример: expand -t 60 file Здесь -t 60 указывает, что символ табуляции нужно заменить на 60(аргумент опции -t) пробелов, а file - имя файла. Мне нужно отличить это имя файла от аргумента опции.

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

Ну почитайте же наконец маны! То, о чём вы говорите, является позиционным аргументов.

Пример юзера beastie решает вашу проблему.

Divius ★★
()
Ответ на: комментарий от Dorif

ещё раз

int ch, tabs = 0;
char *file = NULL;

while ((ch = getopt(argc, argc, "t:") != -1)
        switch (ch) {
        case 't':
                tabs = atoi(optarg);
                break;
        default:
                /* do nothing */
                break;
        }

argc -= optind;
argv += optind;

if (argc)
        file = *argv;

делает именно то, о чём ты спрашиваеш

beastie ★★★★★
()
Ответ на: комментарий от Divius

Значит я не совсем в код врубился. Сейчас ещё раз попробую.)

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

в optind хранится кло-во аргументов обработанных getopt().

соответственно после отнятия optind от общего числа аргументов и инкрементации вектора argv на optind:

argc -= optind;
argv += optind;
у тебя остаётся то, что getopt() не обработал.

profit

PS: между прочем это всё описанно в мане

beastie ★★★★★
()
Ответ на: комментарий от Dorif

как обычно:

#include <err.h>
#include /* ... */

extern  char *__progname;
FILE   *fd[3];        /* we expect 3 file names as arguments */
int     i;

/* getopt() part skipped, see above */
/* argv[0] -- first arg after getopt, argv[1] -- second arg after getopt, and so on */

if (argc != 3)
        errx(1, "usage: %s [args] first second third\n", __progname);

for (i = 0; i < 3; i++) {
        fd[i] = fopen(argv[i], "r");
        if (fd[i] == NULL)
                err(1, "something went terribly wrong, panic!");
}

beastie ★★★★★
()
Ответ на: комментарий от beastie

Так, а если кол- во файлов неизвестно? Пользователь может передать их хоть тыщу, хоть миллион. Предалагаю свой код:

for(int i=0;i<argc;++i){
int fd=open(argv[i],O_RDONLY);
if(fd<0)...//тут должна быть обработка ошибок...
//какие- то действия
close(fd);
}
Работать будет?

Dorif ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.