当前位置:网站首页>用于解析命令行参数的 C argc 和 argv 示例
用于解析命令行参数的 C argc 和 argv 示例
2022-07-19 09:54:00 【华为云】
每当您在终端上执行程序时,您都可以传递一些程序所期望的参数,这些参数可以在程序执行期间使用。在这里,系统提供内部设施来维护在执行程序时从用户传递的所有参数。这些参数称为“命令行参数”。
在本文中,我们将对命令行参数的理解映射到工作程序,以便以清晰明了的方式更好地理解它。但是在开始程序之前,我们应该知道系统如何提供命令行参数的便利。众所周知,每个 C 程序都必须有 main() 函数,而命令行参数的功能由 main() 函数本身提供。当在程序中使用下面的声明时,程序可以使用/操作命令行参数。
int main (int argc, char *argv[])
在这里,argc 参数是在执行时传递给可执行文件的总命令行参数的计数(包括作为第一个参数的可执行文件的名称)。argv 参数是在执行时传递给可执行文件的每个命令行参数的字符串数组。如果您是 C 编程新手,您应该首先了解C 数组的工作原理。
下面给出的是使用命令行参数的工作程序。
#include <stdio.h> int main (int argc, char *argv[]) { int i=0; printf("\ncmdline args count=%s", argc); /* First argument is executable name only */ printf("\nexe name=%s", argv[0]); for (i=1; i< argc; i++) { printf("\narg%d=%s", i, argv[i]); } printf("\n"); return 0; }
下面给出的是程序执行时的输出。
$ ./cmdline_basic test1 test2 test3 test4 1234 56789cmdline args count=7 exe name=./cmdline_basic arg1=test1 arg2=test2 arg3=test3 arg4=test4 arg5=1234 arg6=56789
在上面的输出中,我们可以看到总参数计数是由 main() 的“argc”参数内部维护的,它的值是“7”(其中一个参数是可执行文件名,“6”是传递给程序的参数)。而且,所有参数值存储在 main() 的“argv”参数中,该参数是字符串数组。这里,main() 函数将每个参数值存储为字符串。我们可以看到,遍历“argv”数组,我们可以获得程序中所有传递的参数。
还有一个 main () 函数的声明,它提供了额外的工具来处理程序内部的环境变量。就像在 argv[] 数组中维护的参数一样,main() 函数具有将所有系统环境变量维护为字符串数组的内部工具,这些字符串可以作为 main() 函数的参数。下面给出的是声明。
int main (int argc, char *argv[], char **envp)
下面给出的是使用命令行参数和环境变量的工作程序。
#include <stdio.h>int main (int argc, char *argv[], char **env_var_ptr) {int i=0;printf("\ncmdline args count=%d", argc);/* First argument is executable name only */printf("\nexe name=%s", argv[0]);for (i=1; i< argc; i++) { printf("\narg%d=%s", i, argv[i]); }i=0;while (*env_var_ptr != NULL) { i++; printf ("\nenv var%d=>%s",i, *(env_var_ptr++)); }printf("\n");return 0;}
上述程序的输出如下。
$ ./env test1 test2cmdline args count=3 exe name=./env arg1=test1 arg2=test2 env var1=>SSH_AGENT_PID=1575 env var2=>KDE_MULTIHEAD=false env var3=>SHELL=/bin/bash env var4=>TERM=xterm env var5=>XDG_SESSION_COOKIE=5edf27907e97deafc70d310550995c84-1352614770.691861-1384749481 env var6=>GTK2_RC_FILES=/etc/gtk-2.0/gtkrc:/home/sitaram/.gtkrc-2.0:/home/sitaram/.kde/share/config/gtkrc-2.0 env var7=>KONSOLE_DBUS_SERVICE=:1.76 env var8=>KONSOLE_PROFILE_NAME=Shell env var9=>GS_LIB=/home/sitaram/.fonts env var10=>GTK_RC_FILES=/etc/gtk/gtkrc:/home/sitaram/.gtkrc:/home/sitaram/.kde/share/config/gtkrc env var11=>WINDOWID=29360154 env var12=>GNOME_KEYRING_CONTROL=/run/user/sitaram/keyring-2Qx7DW env var13=>SHELL_SESSION_ID=f7ac2d9459c74000b6fd9b2df1d48da4 env var14=>GTK_MODULES=overlay-scrollbar env var15=>KDE_FULL_SESSION=true env var16=>http_proxy=http://10.0.0.17:8080/ env var17=>USER=sitaram env var18=>LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: env var19=>XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0 env var20=>XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0 env var21=>SSH_AUTH_SOCK=/tmp/ssh-kIFY5HttOJxe/agent.1489 env var22=>ftp_proxy=ftp://10.0.0.17:8080/ env var23=>SESSION_MANAGER=local/Sitaram:@/tmp/.ICE-unix/1716,unix/Sitaram:/tmp/.ICE-unix/1716 env var24=>DEFAULTS_PATH=/usr/share/gconf/kde-plasma.default.path env var25=>XDG_CONFIG_DIRS=/etc/xdg/xdg-kde-plasma:/etc/xdg env var26=>DESKTOP_SESSION=kde-plasma env var27=>PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games env var28=>PWD=/home/sitaram/test_progs/cmdline env var29=>socks_proxy=socks://10.0.0.17:8080/ env var30=>KONSOLE_DBUS_WINDOW=/Windows/1 env var31=>KDE_SESSION_UID=1000 env var32=>LANG=en_IN env var33=>GNOME_KEYRING_PID=1478 env var34=>MANDATORY_PATH=/usr/share/gconf/kde-plasma.mandatory.path env var35=>UBUNTU_MENUPROXY=libappmenu.so env var36=>KONSOLE_DBUS_SESSION=/Sessions/1 env var37=>https_proxy=https://10.0.0.17:8080/ env var38=>GDMSESSION=kde-plasma env var39=>SHLVL=1 env var40=>HOME=/home/sitaram env var41=>COLORFGBG=15;0 env var42=>KDE_SESSION_VERSION=4 env var43=>LANGUAGE=en_IN:en env var44=>XCURSOR_THEME=Oxygen_White env var45=>LOGNAME=sitaram env var46=>XDG_DATA_DIRS=/usr/share/kde-plasma:/usr/local/share/:/usr/share/ env var47=>DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-mnJhMvd4jG,guid=435ddd41500fd6c5550ed8d2509f4374 env var48=>LESSOPEN=| /usr/bin/lesspipe %s env var49=>PROFILEHOME= env var50=>XDG_RUNTIME_DIR=/run/user/sitaram env var51=>DISPLAY=:0 env var52=>QT_PLUGIN_PATH=/home/sitaram/.kde/lib/kde4/plugins/:/usr/lib/kde4/plugins/ env var53=>LESSCLOSE=/usr/bin/lesspipe %s %s env var54=>XAUTHORITY=/tmp/kde-sitaram/xauth-1000-_0 env var55=>_=./env env var56=>OLDPWD=/home/sitaram/test_progs$
在上面的输出中,我们可以看到所有系统环境变量都可以得到main()函数的第三个参数,在程序中遍历并显示在输出中。
将命令行参数传递给程序和操作参数
下面给出的是处理命令行参数的程序。
#include <stdio.h>#include <stdlib.h>int main (int argc, char *argv[]) {int i=0;int d;float f;long int l;FILE *file = NULL;printf("\ncmdline args count=%d", argc);/* First argument is executable name only */printf("\nexe name=%s", argv[0]);for (i=1; i< argc; i++) { printf("\narg%d=%s", i, argv[i]); }/* Conversion string into int */d = atoi(argv[1]);printf("\nargv[1] in intger=%d",d);/* Conversion string into float */f = atof(argv[1]);printf("\nargv[1] in float=%f",f);/* Conversion string into long int */l = strtol(argv[2], NULL, 0);printf("\nargv[2] in long int=%ld",l);/*Open file whose path is passed as an argument */file = fopen( argv[3], "r" );/* fopen returns NULL pointer on failure */if ( file == NULL) { printf("\nCould not open file"); }else { printf("\nFile (%s) opened", argv[3]); /* Closing file */ fclose(file); }printf("\n");return 0;}
上述程序的输出如下。
$ ./cmdline_strfunc 1234test 12345678 /home/sitaram/test_progs/cmdline/cmdline_strfunc.ccmdline args count=4 exe name=./cmdline_strfunc arg1=1234test arg2=12345678 arg3=/home/sitaram/test_progs/cmdline/cmdline_strfunc.c argv[1] in intger=1234 argv[1] in float=1234.000000 argv[2] in long int=12345678 File (/home/sitaram/test_progs/cmdline/cmdline_strfunc.c) opened
在上面的输出中,我们可以看到命令行参数可以在程序中进行操作;所有参数均以字符串形式获取,可以转换为整数、浮点数、长整数,如程序所示。即使是任何字符串,如果作为任何文件的路径传递,程序可以使用该文件处理操作哦那个文件。我们可以在上面的程序中看到, (/home/sitaram/test_progs/cmdline/cmdline_strfunc.c ) 文件路径作为命令行参数传递,该参数在程序内部用于打开和关闭文件。
获取选择() API
如果我们对命令行参数进行更多探索,我们将拥有非常强大的 API——getopt()。它有助于程序员解析命令行选项。程序员可以为 getopt() 提供强制或可选命令行选项列表。它可以根据程序预期的命令行选项确定命令行选项是有效还是无效。很少有 getopt() 特定的内部变量,例如“optarg、optopt、opterr”
- Optarg:包含指向命令行有效选项参数的指针
- Optopt:如果缺少必需的命令行选项,则包含命令行选项
- Opterr:当提供无效选项或未给出强制命令行选项的值时设置为非零
下面给出了理解命令行选项解析的基本程序。
#include <stdio.h>#include <unistd.h>int main (int argc, char *argv[]) {int opt = 0;char *in_fname = NULL;char *out_fname = NULL;while ((opt = getopt(argc, argv, "i:o:")) != -1) { switch(opt) { case 'i': in_fname = optarg; printf("\nInput option value=%s", in_fname); break; case 'o': out_fname = optarg; printf("\nOutput option value=%s", out_fname); break; case '?': /* Case when user enters the command as * $ ./cmd_exe -i */ if (optopt == 'i') { printf("\nMissing mandatory input option"); /* Case when user enters the command as * # ./cmd_exe -o */ } else if (optopt == 'o') { printf("\nMissing mandatory output option"); } else { printf("\nInvalid option received"); } break; } }printf("\n");return 0; }
下面给出了上述程序的输出,其中包含一些命令行选项的组合:
Case1:$ ./cmdline_getopt -i /tmp/input -o /tmp/outputInput option value=/tmp/input Output option value=/tmp/outputCase2:$ ./cmdline_getopt -i -o /tmp/outputInput option value=-oCase3:$ ./cmdline_getopt -i ./cmdline_getopt: option requires an argument -- 'i'Missing mandatory input optionCase4:$ ./cmdline_getopt -i /tmp/input -o./cmdline_getopt: option requires an argument -- 'o' Input option value=/tmp/input Missing mandatory output optionCase5:$ ./cmdline_getopt -k /tmp/input ./cmdline_getopt: invalid option -- 'k'Invalid option received
在上述程序中,'i' 和 'o' 被视为使用 getopt() API 的程序的强制输入和输出命令行选项。
我们现在将对上述程序中执行的每个案例进行基本解释:
- 在 Case1 中,提供了两个强制命令行选项及其参数,这些选项在程序切换条件的前两种情况下得到了正确处理。
- 在 Case2 中,没有给出强制输入选项的值,但我们可以看到 getopt() 不够智能,将“-o”视为“I”命令行选项的值。getopt() 不是错误情况,但程序员自己可以添加智能来处理这种情况。
- 在 Case3 中,仅指定了没有其值的命令行选项,这是强制选项,因此在这种情况下 getopt() 将返回“?” 并且“optopt”变量设置为“i”以确认缺少强制输入选项的值。
- 在 Case4 中,缺少强制输出选项的值。
- 在 Case5 中,给出了无效的命令行选项,它不是强制性的或可选的命令行选项。在这种情况下,getopt() 返回 '?' 并且 optopt 未设置,因为它是 getopt() 不期望的未知字符。
边栏推荐
- 2022-07-18:以下go语言代码输出什么?A:Groutine;B:Main;C:Goroutine;D:GoroutineMain。 package m
- PostgreSQL two months, how to calculate the total number of months?
- c# LeetCode刷题笔记5- 一维数组的动态和
- Outils de construction
- Detailed explanation of feign custom configuration
- Panda3D drawing cube
- Paper reading: linknet: expanding encoder representations foreefficient semantic segmentation
- Pytorch3d reference tutorial
- Go language constants and operators
- kmeans手写实现与sklearn接口
猜你喜欢
美国土安全部无授权下追踪国内外民众手机定位 花费数百万美元
CNN结构设计技巧:兼顾速度精度与工程实现
MongoDB 安全认证
It costs millions of dollars to track the mobile location of people at home and abroad without authorization
性能提升30倍丨基于 DolphinDB 的 mytt 指标库实现
Reading notes - shopping mall
Feign自定义配置详解
Is it really possible to make reports with zero coding?
日期类的简易实现
Some questions about deploying Ogg microservices
随机推荐
12. Talk about the implementation principle of single sign on in the project?
Feign自定义配置详解
什么是更适合中国企业的CRM选型标准?
NVIDIA开源了基于PyTorch的3D深度学习的综合库
C# LeetCode刷题笔记3-.统计匹配检索规则的物品数量
美国土安全部无授权下追踪国内外民众手机定位 花费数百万美元
C leetcode question brushing notes 3- Count the number of items matching the search rule
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(7)-Fiddler状态面板-QuickExec命令行
Go语言 流程控制
Yum -y install MySQL in Linux why is MariaDB by default? And MySQL Yum source configuration
实验3 MGRE 综合实验
【数据库】索引
动态内存管理
Dynamic memory management
Fully Convolutional Networks for Surface Defect Inspection in IndustrialEnvironment-论文阅读笔记
Automatic Metallic Surface Defect Detection and Recognition with Convolutional NeuralNetworks-论文阅读笔记
vivo官网APP全机型UI适配方案
0055 PHP language introduction and HelloWorld
1305_ Basic queue function description of FreeRTOS
PM必须掌握的产品发展的神奇曲线