создание пользовательских настроек в Unix - PullRequest
0 голосов
/ 29 апреля 2018

Я хочу создать новые опции в cat, используя файл c

Я новичок в Unix, поэтому не знаю, что использовать.

Я хочу скомпилировать

./mycat -s 16 foo 

16 это размер буфера, а foo это имя файла

с использованием файла mycat.c и кода ниже

#include <stdio.h> /* fprintf */
#include <unistd.h> /* getopt */
#include <stdlib.h> /* exit */

/* debug mode (-d option) */
int is_debug = 0;

/* prints log message to stderr only when -d is available */
#define LOG(fmt, ...) do { if (is_debug) fprintf(stderr, fmt "\n", __VA_ARGS__); } while (0)


/* Non-portable functions for checking stdio's buffer size, etc. */

/* checks if the given stream is line-buffered */
int is_stdio_linebuffered(FILE *stream) {
    return (stream->_flags & __SLBF) > 0;
}

/* checks if the given stream is NOT buffered */
int is_stdio_unbuffered(FILE *stream) {
    return (stream->_flags & __SNBF) > 0;
}

/* obtains the buffer size of the given stream */
int stdio_buffer_size(FILE *stream) {
return stream->_bf._size;
}

int main(int argc, char **argv) {
    int opt, i;
    while ((opt = getopt(argc, argv, "dm:")) != -1) {
    switch (opt) {
    case 'd':
        is_debug = 1;
        break;
    case 'm':
        fprintf(stderr, "%s: message is '%s'\n", argv[0], optarg);
        break;
    case 'i': ???????????????????????????????????
    default:
        fprintf(stderr, "Usage: %s [-d] [-m message] args...\n", argv[0]);
        exit(EXIT_FAILURE);
    }
}

  for (i = optind; i < argc; i++) {
      LOG("[%d] %s", i, argv[i]);
  }
  return 0;
}

поэтому в файл c нужно добавить код

но я не знаю, какую функцию использовать

как сделать параметр -i, который получает размер буфера и имя файла?

1 Ответ

0 голосов
/ 29 апреля 2018

Подпись getopt() является

int getopt(int argc, char * const argv[], const char *optstring);

В optstring должны быть указаны символы опции. За символом опции следует одиночный :, только если ему всегда требуется аргумент. Для необязательного аргумента используются две точки с запятой, а для тех, у кого всегда нет аргументов, точка с запятой отсутствует.

Вам нужна опция -s, которая принимает целочисленный аргумент.

При использовании getopt() есть две другие опции d и m, которые не принимают аргумент (я предположил, что m не принимает аргумент, как вы хотели ./mycat -s 16 foo для компиляции . Если хотите, измените его на необязательный аргумент.

То есть getopt() должно быть

while ((opt = getopt(argc, argv, "dms:")) != -1) {
    ....
    ....
} 

И в case 's': оператора switch

case 's': 
iopt = strtol(optarg, &dp, 10); 
if(iopt==0 && errno == ERANGE)
{
    errno = 0;
    perror("Number out of range");
}
else if(*dp != 0)
{
    printf("\nNot a numeric value. Non number part found");
}
break;

optarg будет указывать на начало строки, которая является аргументом опции s.

Так как он нужен нам как число, вам нужно преобразовать строку в число.

strtol() используется для этого. В случае успеха возвращает номер типа long.
Если число слишком велико, чтобы содержаться в long, оно возвращает 0 и устанавливает errno в ERANGE. Чтобы проверить эти коды ошибок, необходимо указать errno.h.

Вы можете использовать другие функции в том же семействе, что и strtol(), чтобы получить значения других типов. Например: strtoll() для long long.

...