Linux下C程式命令列引數處理
POSIX標準中對程式名、引數作了如下相關約定:
* 程式名不宜少於2個字元且不多於9個字元;
* 程式名應只包含小寫字母和阿拉伯數字;
* 選項名應該是單字元活單數字,且以短橫‘-‘為字首;
* 多個不需要選項引數的選項,可以合併。(譬如:foo -a -b -c ---->foo -abc)
* 選項與其引數之間用空白符隔開;
* 選項引數不可選。
* 若選項引數有多值,要將其併為一個字串傳進來。譬如:myprog -u "arnold,joe,jane"。這種情況下,需要自己解決這些引數的分離問題。
* 選項應該在操作數出現之前出現。
* 特殊引數‘--'指明所有引數都結束了,其後任何引數都認為是運算元。
* 選項如何排列沒有什麼關係,但對互相排斥的選項,如果一個選項的操作結果覆蓋其他選項的操作結果時,最後一個選項起作用;如果選項重複,則順序處理。
* 允許運算元的順序影響程式行為,但需要作文件說明。
* 讀寫指定檔案的程式應該將單個引數'-'作為有意義的標準輸入或輸出來對待。
GNU鼓勵程式設計師使用--help、--verbose等形式的長選項。這些選項不僅不與POSIX約定衝突,而且容易記憶,另外也提供了在所有GNU工具之間保持一致性的機會。GNU長選項有自己的約定:
* 對於已經遵循POSIX約定的GNU程式,每個短選項都有一個對應的長選項。
* 額外針對GNU的長選項不需要對應的短選項,僅僅推薦要有。
* 長選項可以縮寫成保持惟一性的最短的字串。
* 選項引數與長選項之間或通過空白字元活通過一個'='來分隔。
* 選項引數是可選的(只對短選項有效)。
* 長選項允許以一個短橫線為字首。
C程式通過argc和argv引數訪問它的命令列引數,通過main()函式呼叫和處理:int main(int argc, char *argv[])。一般情況下,我們事先約定好引數的順序位置,然後在main函式中進行簡單處理。這種方式實現比較簡單,然後使用者使用起來很不方便,Linux下的各種工具的命令列引數可以是不分先後次序的。幸運的是,Linux為C程式設計師提供了相關的命令列引數解析函式:getopt()和getopt_long(),分別用於處理短選項和長選項,當然後者可以同時處理短、長選項。函式原型如下:
#include <unistd.h>
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
getopt() 函式是一個標準庫呼叫,可允許使用直接的 while/switch 語句方便地逐個處理命令列引數和檢測選項(帶或不帶附加的引數)。getopt_long() 允許在幾乎不進行額外工作的情況下處理更具描述性的長選項,非常受開發人員的歡迎。下面用筆者開發的一個Daemon程式wsiod中的引數處理來說明具體的處理過程。wsiod引數幫助資訊如下:
[liuag] /home/liuag/workspace/WSIO/WSIO-1.3/server > ./wsiod --help
Usage: wsiod [OPTION]
WSIO server based on web service.
Mandatory arguments to long options are mandatory for short options too.
-h, --host hostname in soap_bind, default is host which the service runs
-p, --port port which the sercer runs on, default is 8080
-b, --backlog request backlog, default is 100
-t, --type server type, default is COMMON
-k, --keepalive attempt to keep socket connections alive
-c, --chunk use HTTP chunking
-d, --dime use DIME encoding
-D, --debug print debug info
--help print this help
Server type:
COMMON the simplest server
STANDALONE stand-alone server, which can run on port 80
MULTITHREAD multi-thread stand-alone server
POOL using a pool of servers
QUEUE using a queue of requests for server
GSI prethreaded server with GSI enabled
Report bugs to <[email protected]>.
wsiod引數處理實現C程式段如下:
#include <unistd.h>
#include <getopt.h>
enum SERVERTYPE{COMMON, STANDALONE, MULTITHREAD, POOL, QUEUE, GSI};
int keepalive = 0, dime = 0, chunk = 0;
/* WSIO server main function */
int main(int argc, char **argv)
{
int c;
char host[128] = "localhost";
char log_buf[LOGBUFSZ];
int port = 8080, backlog = 100;
enum SERVERTYPE servertype = COMMON;
int helpflg = 0,
errflg = 0,
debug = 0;
struct option longopts[] =
{
{"host", 1, 0, 'h'},
{"port", 1, 0, 'p'},
{"backlog", 1, 0, 'b'},
{"type", 1, 0, 't'},
{"keepalive", 0, 0, 'k'},
{"chunk", 0, 0, 'c'},
{"dime", 0, 0, 'd'},
{"debug", 0, 0, 'D'},
{"help", 0, &helpflg, 1},
{0, 0, 0, 0}
};
while ((c = getopt_long (argc, argv, "h:p:b:t:kcdD", longopts, NULL)) != EOF)
{
switch(c)
{
case 'h':
sprintf(host, "%s", optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'b':
backlog = atoi(optarg);
break;
case 't':
switch(*optarg)
{
case 'C':
servertype = COMMON;
break;
case 'S':
servertype = STANDALONE;
break;
case 'M':
servertype = MULTITHREAD;
break;
case 'P':
servertype = POOL;
break;
case 'Q':
servertype = QUEUE;
break;
case 'G':
servertype = GSI;
default:
break;
}
break;
case 'k':
keepalive = 1;
break;
case 'c':
chunk = 1;
break;
case 'd':
dime = 1;
break;
case 'D':
debug = 1;
break;
case '?':
errflg++;
break;
default:
break;
}
}
if(helpflg || errflg)
{
fprintf(stderr,"Usage: wsiod [OPTION]/n/n%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
"WSIO server based on web service./n",
"Mandatory arguments to long options are mandatory for short options too./n",
"/t-h, --host hostname in soap_bind, default is host which the service runs/n ",
"/t-p, --port port which the sercer runs on, default is 8080/n",
"/t-b, --backlog request backlog, default is 100/n",
"/t-t, --type server type, default is COMMON/n",
"/t-k, --keepalive attempt to keep socket connections alive/n",
"/t-c, --chunk use HTTP chunking/n",
"/t-d, --dime use DIME encoding/n",
"/t-D, --debug print debug info/n",
"/t --help print this help/n/n",
"Server type:/n",
"/tCOMMON the simplest server/n",
"/tSTANDALONE stand-alone server, which can run on port 80/n"
"/tMULTITHREAD multi-thread stand-alone server/n",
"/tPOOL using a pool of servers/n",
"/tQUEUE using a queue of requests for server/n",
"/tGSI prethreaded server with GSI enabled/n/n",
"Report bugs to <[email protected]>./n"
);
exit(0);
}
/* 省略部分 */
return 0;
}
相關推薦
Linux下C程式命令列引數處理
Linux下開發C程式,甚至是GUI程式,都可能需要處理複雜的命令列引數。健全、可靠的複雜命令列引數處理機制,可使程式方便使用,也更顯專業。Linux下幾乎所有的命令都提供了引數處理機制,包括短選項和長選項。 POSIX標準中對程式名、引數作了如下相關約定:
windows下C++程式命令列引數讀取
linux下,命令列引數的讀取,可以使用系統函式getopt,還好Ludvik Jerabek實現了一個開源的getopt,我們可以直接拿來在windows程式設計中用。 STATIC_GETOPT 然後就可以體會getopt帶來的便利了: bool isHelp
Linux 程式設計學習筆記----命令列引數處理
問題引入----命令列引數及解析 在使用linux時,與windows最大的不同應該就是經常使用命令列來解決大多數問題.比如下面這樣的: 而顯然我們知道C語言程式的入口是mian函式,即是從main函式開始執行,而main函式的原型是: int main( int a
boost之program_option-命令列引數處理(霜之小刀)
歡迎轉載和引用,若有問題請聯絡 若有疑問,請聯絡 Email : [email protected] QQ:2279557541 命令列的引數處理什麼xxx –xxx -x=xx -x 這種東西如果我們自己從argc,argv裡面提取,我相信大家
linux下c程式 daemon、fork與建立pthread的順序問題
近期發如今寫linux c服務程式的時候,daemon與執行緒建立之間出現故障。發現程式在daemon之後,起的執行緒就全掛了。 查過一些文件之後,最終知道了why. daemon函式的操作事實上非常easy, 1.fork一個程序,2.處理
Linux下C程式動態庫的生成和呼叫
Linux下C程式動態庫的生成和呼叫 文章目錄 Linux下C程式動態庫的生成和呼叫 1 動態庫的打包和呼叫 2 靜態庫打包和呼叫 3 常用命令 4 gcc 和 g++ 區別 5 編譯和連結的理解
C程式設計--命令列引數(argc 和 argv[])
概念 命令列引數是使用 main() 函式引數來處理的,其中,argc 是指傳入引數的個數,argv[] 是一個指標陣列,指向傳遞給程式的每個引數。 具體寫法:int main(int argc,char* argv[ ]) //注:main()括號內是固定的寫法。 或者寫成:int
python命令列引數處理:argparse、optparse和getopt
一 命令列引數: (1)在python中: *sys.argv:命令列引數的列表。 *len(sys.argv):命令列引數的個數(argc)。 *python中提供了三個模組來輔助處理命令列引數:getopt,optparse和argparse。 (2)術語: *arg
C語言命令列引數的使用
之前曾經使用過很多次c語言的命令列引數了,但是總是每次使用的時候都不太確定,需要重新查資料,這次來個總結。c語言的命令列引數非常簡單,只需要一個簡單的例子就可以說明: #include <stdio.h> void main(int argc,char
linux中getopt_long解析命令列引數(附上windows上的getopt_long原始碼)
getopt_long支援長選項的命令列解析,使用man getopt_long,得到其宣告如下: #include <getopt.h> int getopt_long(int argc, char * const argv[
C 語言命令列引數解析
C語言原始碼必須有且只有一個的函式是main函式,我們知道函式可以有引數,那麼main函式有沒有引數呢? 顯然是有的,而且它是固定的,只有兩個,第一個是整型變數(argc),第二個是字元型指標陣列(a
UNIX/LINUX下C++程式計時方法
最近簡單學習了下Linux下C++程式計時的一些函式和方法,總結如下. 方法一: 如果是想統計某個程式的執行時間,那麼可以使用 time ./a.out 方法二: 如果是想對某個函式或者語句進行計時,那麼有別的方法。比如說,gettimeofday函式
Shell指令碼學習-命令列引數處理
在Linux的Shell中怎樣處理tail -n 10 access.log這樣的命令列選項呢?這是被別人問起的一個問題,好好學習了一下,進行總結如下: 在bash中,可以用以下三種方式來處理命令列引數,每種方式都有自己的應用場景。 1.直接處理,依次
Linux 下c++程式中列印系統當前時間
//方案一,將當前時間折算為秒級,再通過相應的時間換算即可 //此檔案必須是c++檔案 /* #include<iostream> #include<ctime> using namespace std
C/C++中命令列引數的原理總結
在c/c++中,命令列引數的傳遞是利用main進行形參傳遞實現 【1】了實現命令列引數我們將使用main(int argc,char* argv[])這樣的形式進行定義argc和argv可以換成你自己喜歡的名稱不一定要用argv,argc這些形式只是習慣而已,char*
Windows下C語言命令列編譯器的環境變數設定
安裝完VS任意一個版本後只要進行相應的環境變數的設定就能用命令列編譯C語言程式,此方法完美解決win8下VC6不相容又不想執行臃腫的VS 將該指令碼命令在命令列中執行一下即完成環境變數的設定,這裡以VS2012為例,其他版本需做相應更改,如VS2013,就設定VS130Co
Linux環境下C程式設計指南---gcc 編譯器常用的命令列引數一覽
1. gcc -E source_file.c-E,只執行到預編譯。直接輸出預編譯結果。2. gcc -S source_file.c -S,只執行到原始碼到彙編程式碼的轉換,輸出彙編程式碼。3. gcc -c source_file.c-c,只執行到編譯,輸出目標檔案。4. gcc (-E/S/c/) so
【C程式編譯連結】gcc使用命令介紹 gcc的使用簡介與命令列引數說明
1.gcc或者g++安裝rpm -qa|grep gcc ==>檢查gcc是否安裝gcc -v ==>檢查gcc版本 編譯器會在可執行檔案中植入一些資訊,可執行檔案會變大。一般開發時候使用 -g ,編譯一個 “release 版本” 時不使用 -g 編譯。gcc如果是最新的則不重
一個簡單的C#命令列引數程式
新建一個c#控制檯程式,命名為ConsoleApplication1 程式主體如下 class Program { static void Main(string[] args) {
DOS(CMD)下批處理換行問題/命令列引數換行 arg ms-dos
程式來自:http://hi.baidu.com/nxhujiee/item/ae52584c36a13d0f6dc2f0f8 DOS(CMD)下批處理換行問題本人經常寫一些DOS批處理檔案,由於批處理中命令的參考較多且長,寫在一行太不容易分辨,所以總想找個辦法把一條命令