Linux下 头文件<getopt.h> 及其函数的应用

本文内容摘抄自:https://www.cnblogs.com/qingergege/p/5914218.html

函数一:

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

参数1、2为 main函数的输入参数,参数3 为选项字符串,函数返回值为选项字符。

<getopt.h 文件内部的参数:

1、 extern char* optarg ;   用于保存选项。

2、 extern int   optind,  用来记录下一个检索位置。

3、 extern int   opterr,   是否将错误的信息输出到stderr,为0时表示不输出。

4、 extern int   optopt,    表示不在选项字符串optstring中的选项。

先来看一条指令: gcc  helloworld.c  -o  helloworld.out;  这条指令中的-o就是命令行的选项,而后面的helloworld.out 就是选项-o选项所携带的参数。 有些选项是不带参数的,而这样不带参数的选项可以写在一起, 比如说有两个选项 -c和-d,这两个选项都不带参数,那么他们是可以写在一起的,即:-cd 。

关于选项字符串: 比如 “a:b:cd::e”,这就是一个选项字符串。对应到命令行就是 -a, -b, -c, -d, -e 。 冒号表示参数,一个冒号就表示这个选项后面必须带有参数。这个参数可以和选项连在一起,也可以用空格隔开,比如:-a123 和 -a 123 ,都表似乎123为-a的参数。两个冒号就表示这个选项的参数是可选的,即可以有参数也可以没有参数,但要注意有参数时参数与选项之间不能有空格。

一个例子:

/*
 ============================================================================
 Name        : test.c
 Author      : lgh
 ============================================================================
 */

#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
    int ch;
    printf("\n\n");
    printf("optind:%d, opterr:%d\n",optind,opterr);
    printf("-----------------------------------------------------------\n");

    while((ch = getopt(argc, argv, "ab:c:de::")) != -1)
    {
        switch(ch)
        {
           case ‘a‘:
               printf("a\n\n");
               printf("the argument of -a is %s\n\n",optarg);
               break;

           case ‘b‘:
                 printf("b\n\n");
                 printf("the argument of -b is %s\n\n",optarg);
                 break;

           case ‘c‘:
                 printf("c\n\n");
                 printf("the argument of -c is %s\n\n",optarg);
                 break;

           case ‘d‘:
                 printf("d\n\n");
                 break;

           case ‘e‘:
               printf("e\n\n");
               printf("the argument of -e is %s\n\n",optarg);
               break;

           case ‘?‘:
               printf("unknown option: %c\n",(char)optopt);
               break;
        }
        printf("下一次起始搜索位置:optind = %d\n",optind);
        printf("-----------------------------------------------------------\n");
        printf("\n\n");
    }
}

编译后命令执行  ./test  -b  "hello world"

输出结果为:

optind:1, opterr:1
-----------------------------------------------------------
b

the argument of -b is hello world

下一次起始搜索位置:optind = 3
-----------------------------------------------------------

可以看到optind 和 opterr的初始值都为1 ,opterr非零表示如果发生错误,会将错误输出到stderr上。

int main(int argc, char* argv[]);   argc表示参数的个数,argv[]表示每个参数字符串。 对于./test -b "hello world" 命令,argc就为3,argv[]分别表示./test   -b  "hello world" , 实际上真正的参数从 -b 开始,也就是argv[1] ,所以optind的初始值就是1。

当执行getopt()函数时,会依次扫描每一个命令行参数(下标1开始),第一个-b是一个选项,而且这个选项在选项字符串optstring中有,b后面有冒号表示b后面必须带有参数, “hello world”就是它的参数。所以这个命令行是符合要求的。至于执行后optind为什么是3,这是因为optind是下一次getopt()函数要从argv[3]开始搜索。当然,这个例子argv[3]已经没有了,此时getopt()函数会返回-1,结束while循环。

再次输入一行命令: ./test   -b  "hello world"  -c1234

输出结果为:

optind:1, opterr:1
-----------------------------------------------------------
b

the argument of -b is hello world

下一次起始搜索位置:optind = 3
-----------------------------------------------------------

c

the argument of -c is 1234

下一次起始搜索位置:optind = 4
-----------------------------------------------------------

对于这个过程,最开始optind=1 ,找到选项-b 和他的参数“hello world” ,之后搜索起始位置跳至argv[3] 找到 -c和他的参数1234(选项和参数是连在一起的),由于-c1234是写在一起的,所以他俩一起占用argv[3] ,之后搜索起始位置跳至 argv[4] ,而argv[4]为空,这样getopt()函数就会返回-1,循环结束。

再次输入命令:  ./test  -z 123

输出结果为:

optind:1, opterr:1
-----------------------------------------------------------
./test: invalid option -- ‘z‘
unknown option: z
下一次起始搜索位置:optind = 2
-----------------------------------------------------------

其中./test: invalid option -- ‘z‘ 就是输出到stderr的错误输出 ,如果把opterr设置为0那么就不会有这条输出。

再次输入命令:  ./test  -zheng

输出结果为:

optind:1, opterr:1
-----------------------------------------------------------
./test: invalid option -- ‘z‘
unknown option: z
下一次起始搜索位置:optind = 1
-----------------------------------------------------------

./test: invalid option -- ‘h‘
unknown option: h
下一次起始搜索位置:optind = 1
-----------------------------------------------------------

e

the argument of -e is ng

下一次起始搜索位置:optind = 2
-----------------------------------------------------------

由于不带参数的选项可以写在一起,所以当getopt()函数找到-z的时候,发现在optstring中没有,这时候他就认为h也是一个选项,也就是-h 和 -z写在一起了,依次类推,直到找到-e,发现optstring中有。

原文地址:https://www.cnblogs.com/GuanghuiLiu/p/9309513.html

时间: 2024-08-29 19:22:51

Linux下 头文件<getopt.h> 及其函数的应用的相关文章

linux内核头文件kdev_t.h 宏定义解析

kdev_t.h 宏定义解析 这个header file反正不多,直接原因是--遇到了,就搞定它! dev_t 类型的变量定义在linux/types.h 用来保存设备编号--包括主设备号和次设备号.dev_t 是一个32位的数,其中12位用来表示设备号,其余20位用来表示次设备号. 始终不要对这32位是高12位是主设备号还是低2位是主设备号做出假定,不利于代码的可移植性,始终记得使用宏定义来处理dev_t ! 都在这里了: #define MINORBITS 20 //次设备号的占位数目 #d

linux内核头文件 cdev.h 解析

遇到一个内核API--cdev_init 就找到这里来了. #ifndef _LINUX_CDEV_H #define _LINUX_CDEV_H #include <linux/kobject.h #include <linux/kdev_t.h> #include <linux/list.h> struct file_operations; struct inode; struct module; struct cdev { struct kobject kobj; st

头文件 INTRINS.H 的用法

KEIL中头文件INTRINS.H的作用 在C51单片机编程中,头文件INTRINS.H的函数使用起来,就会让你像在用汇编时一样简便. 内部函数 描述 crol_ 字符循环左移_cror_ 字符循环右移_irol_ 整数循环左移_iror_ 整数循环右移_lrol_ 长整数循环左移_lror_ 长整数循环右移_nop_ 空操作8051 NOP 指令_testbit_ 测试并清零位8051 JBC 指令 函数名: _crol_,_irol_,_lrol_原 型: unsigned char _cr

在VC下如何使用头文件unistd.h

头文件unistd.h是Linux/Unix的系统调用,包含了许多UNIX系统服务函数原型,如open.read.write._exit.getpid等函数.在linux下能够编译通过的包含此头文件的程序,在VC下编译时出现了如下问题 fatal error C1083: Cannot open include file: 'unistd.h': No such file or directory 其实解决这个问题的方法并不难,只要在你的默认库文件夹下(我的电脑是D:\Program Files

Microsoft Visual Studio下编译缺少头文件unistd.h解决办法

问题 使用Visual Studio 2012在Win7下编译一个来自于Linux平台的源文件时,要求使用头文件uninstd.h,报错: fatal error C1083: Cannot open include file: 'unistd.h': No such file or directory 解决办法 对于VS2012来说,我们可以在默认库文件夹下(我的电脑是C:\Program Files\Microsoft Visual Studio 10.0\VC\include)添加一个un

文件类型分类:头文件dirent.h中定义的文件类型与linux内文件符号对应关系

头文件 dirent.h 定义了文件类型: enum{    DT_UNKNOWN = 0,         //未知类型    DT_FIFO = 1,            //first in, first out 类似于管道, 有名管道    DT_CHR = 2,             //字符设备文件    DT_DIR = 4,             //目录    DT_BLK = 6,             //块设备文件    DT_REG = 8,          

linux常用头文件及说明

linux常用头文件及说明 1. Linux中一些头文件的作用: <assert.h>:ANSI C.提供断言,assert(表达式)<glib.h>:GCC.GTK,GNOME的基础库,提供很多有用的函数,如有数据结构操作函数.使用glib只需要包含<glib.h><dirent.h>:GCC.文件夹操作函数.struct dirent,struct DIR,opendir(),closedir(),readdir(),readdir64()等 <c

&#8203;Linux下C如何调用PCI Lib函数

Linux下C如何调用PCI Lib函数 在Linux下,可以通过"setpci"和"setpci"命令来访问PCI设备的配置空间,那么能否用程序来访问PCI 配置空间呢?答案当然是肯定的,linux下提供了多个pci库以供应用程序访问.下面就以最常见的为例,从安装.使用和编译的角度分别进行说明. 安装在centos中,用超级用户权限,可用下面的命令查看到和pci访问相关的库包括:libpciaccess.i686 : PCI access librarylibpc

linux下遍历文件夹---opendir等用法

首先要说肯定是头文件,#include <sys/types.h>   #include <dirent.h> linux下遍历文件夹需要用到以下几个函数,其中有三个是必须的,其它几个是可选的. DIR* opendir(const char * name);   失败返回NULL.成功返回DIR结构体.注意DIR前面没有struct,如果加上编译器会warning struct dirent *readdir(struct DIR* dir);   失败返回NULL. void