C 在unix中创建自定义选项

C 在unix中创建自定义选项,c,unix,getopt,C,Unix,Getopt,我想用c文件在cat中创建新选项 我是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_de

我想用c文件在cat中创建新选项

我是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选项来获取缓冲区大小和文件名?

getopt的签名是

在optstring中,必须指定选项字符。选项字符后跟一个:仅当它始终需要参数时。可选参数使用两个分号,始终没有参数的参数不使用分号

您需要一个选项-s,它接受一个整数参数

在使用getopt时,还有另外两个选项d和m不接受参数,我假设m不接受您想要的参数。/mycat-s 16 foo要编译。如果您愿意,可以将其更改为接受可选参数

所以getopt应该是

while ((opt = getopt(argc, argv, "dms:")) != -1) {
    ....
    ....
} 
在switch语句的“s”情况下

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很长时间。

也许可以从阅读getopt的文档开始?要执行此操作,请运行man getopt。检查输出是否缓冲的函数正在执行完全相同的操作,结果可能与您所希望的不同。
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;