C++控制台程序的命令行參數輸入-且支持參數opts擴展


 C++控制台程序的命令行參數輸入

1. C/C++語言中的main函數,經常帶有參數argc,argv,如下:

int main(int argc, char** argv)
int main(int argc, char* argv[])

  argc(第一個形參)必須是整型變量,標識該控制台命令調用中接收到的參數個數,注意,包括該命令程序名字itself。

  argv( 第二個形參)必須是指向字符串的指針數組,用於保存argc個參數的具體數據。注意數組起始索引為0開始,到argc-1結束。即:argv[0]為命令行中可執行程序名本身,argv[1]為命令行中第二個參數的內容,依次類推。

加上形參說明后,因此C程序中的main函數的函數頭應寫為:

 main (int argc,char *argv[])

2. 控制台程序參數獲取

  由於main函數不能被其它函數調用,因此不可能在程序內部取得實際值。那么,在何處把實參值賦予main函數的形參呢? 實際上,main函數的參數值是從操作系統命令行上獲得的。

  如何在操作系統命令行獲取參數呢?

(1)在VS中設置時右鍵項目->屬性->調試->命令參數,在命令參數中添加所需參數,字符串之間用空格分開即可。如果是.txt文件,要放在當前目錄下(.cpp所在目錄)【實質為exe生成目錄位置】,不然找不到。

 

 

(2)或者:假如你的程序是hello.exe,如果在命令行運行該程序,(首先應該在命令行下用 cd 命令進入到 hello.exe 文件所在目錄) 運行命令為:

hello.exe data.txt //.txt也在.exe所在目錄下

 

  注意:調用控制台程序命令行中輸入的參數在位置上,並沒有與控制台程序main函數中 的兩個形參 一 一 對應的。 因為,main的形參只有二個,而命令行中的參數個數原則上未加限制。argc參數表示了命令行中參數的個數(注意:文件名本身也算一個參數),argc的值是在輸入命令行時由系統按實際參數的個數自動賦予的,即,argv[0]為命令行中可執行程序名本身,argv[1]為命令行中第二個參數的內容,依次類推

 

  在調用一個可執行程序時,某些情況下需要向程序傳遞參數。如我們可以在控制台中鍵入notepad.exe,回車后將執行記事本程序。

  如果我們希望在打開notepad時同時打開一個文本文件,可以在notepad.exe 。后面跟上文件的路徑和名字,如notepad.exe   example.txt(文件在當前路徑) 

   

   那么程序中如何能得到這些輸入參數呢?這個工作是編譯器幫我們完成的,編譯器將輸入參數的信息放入main函數的參數列表中。  

  main函數的參數列表保存了輸入參數的信息,第一個參數argc記錄了輸入參數的個數,  第二個參數是字符串數組的,字符串數組的每個單元是char*類型的,指向一個c風格字符串。  

例子如下:

notepad.exe   example.txt   data.txt   train.txt 
第一個參數    第二個參數   第三個參數  第四個參數
因此:argc = 4

 控制台執行上面程序后,程序讀取main函數參數為:   argc是4,就是說argv數組中有四個有效單元  

   argv數組中的第一個單元指向的字符串總是可執行程序的名字,以后的單元指向的字符串依次是程序調用時的參數。

   第一單元argv[0]指向的字符串是"notepad.exe"  
   第二單元argv[1]指向的字符串是"example.txt"  
   第三單元argv[2]指向的字符串是"data.txt"  
   第四單元argv[3]指向的字符串是"train.txt"  

  `上述這個賦值過程是編譯器自動完成的,我們只需要利用argc,argv[]讀出數據就可以了。

 

3. 簡單示例,控制台程序的不同調用方法,及輸出結果:

復制代碼
int main(int argc, char* argv[])
{
    cout << "參數個數:" << argc << endl;
    cout << "參數內容:";
    for (int i = 0; i < argc; ++i)
    {
        cout << argv[i] << endl;
    }

    //std::cout << "Hello World!\n";
    system("pause");
}
復制代碼

(1) 控制台調用:

1、按住Shift鍵,鼠標右鍵快捷方式,先打開Powershell窗口。
2、輸入 start cmd 回車
3、這樣就可以打開cmd窗口了,並且cmd的工作目錄就是當前的目錄。

輸入命令行:

ProjectTest.exe 1111 zhongguo renmin 傳見過 中國人民解放拒絕

輸出:

 

 

(2)利用VSIDE中的控制台參數進行調用:

 

 程序:

復制代碼
#include <iostream>

int main(int argc, char **argv)
{
    while (argc-- > 0)
    {
        //printf("argv[%d]:%s\n", argc, argv[argc]);
        printf("argc:%d,*argv++:%s\n", argc,*argv++);
        //printf("argc:%d,*++argv:%s\n", *++argv);

    }
}
復制代碼

在VS中設置設置 comant argument:

不進行設置時:

 

 

 

設置參數時: 

 

 (3)批處理腳本中.bat文件中,調用可執行文件

 

 

 

 

 

  編輯“main測試.bat”文件內容為:

ProjectTest  Jack 中國 boin747 1.234  3.3333 8888 zhongguo
pause

在cmd運行.bat文件

 

 

 

 雙擊:

 

 

   

  好像識別漢字出現了問題,這里只是測試,能達到示意main函數的傳參即可,我就不深因了。

如果把漢字改為數字和字母,則運行效果如預期:

 

 4. 較為復雜的命令行程序,規范化輸入,編寫規范

  下面摘錄一個例程,該程序用於取出在argv中的命令行選項。在例子中,將支持下列用法:

復制代碼
//C/C++處理main()函數命令行
#include <iostream>
#include <vector>
#include <string>
#include <ctype.h>//調用atoi函數
using namespace std;

const char* const prog_name = "prog";
const char* const prog_version = "version 1.0 (2011/8/24)";

//退出函數
inline void usage(int exit_value = 0){
    cerr<<prog_name<<"  usage!"<<endl;
    exit(exit_value);
}

int main(int argc,char* argv[]){
    //聲明用於記錄用戶指定選項的變量
    bool debug_on = false;
    bool ofile_on = false;
    bool limit_on = false;

    string ofile_name;//記錄出現的輸出文件名
    int limit = -1;//限制值
    vector <string> file_names;//記錄文件名

    cout<<"argc:"<<argc<<endl;
    for(int i = 1;i < argc; ++i){//讀取argv中的每個選項
        //輸出第i+1個參量
        cout<<"argv["<<i<<"]:"<<argv[i]<<endl;

        char *pchar = argv[i];
        switch(pchar[0]){//確定選項類型:-h,-d,-v,-l,-o;或者其他
            case '-':{
                cout<<"case \'-\' found"<<endl;
                switch(pchar[1]){//確定用戶指定的選項:h,d,v,l,o
                    case 'd'://處理調試:
                        cout<<"-d found:debugging turned on!"<<endl;
                        debug_on = true;
                        break;
                    case 'v'://處理版本請求
                        cout<<"-v found:version info displayed!"<<endl;
                        cout<<prog_name<<":"<<prog_version<<endl;
                        return 0;
                    case 'h'://處理幫助
                        cout<<"-h found:help info!"<<endl;
                        usage();
                    case 'o'://處理輸出文件
                        cout<<"-o found:output file!"<<endl;
                        ofile_on = true;
                        break;
                    case 'l'://處理限制量
                        cout<<"-l found:resorce limit!"<<endl;
                        limit_on = true;
                        break;
                    default://無法識別的選項
                        cerr<<prog_name<<":error:unrecognition option -:"<<pchar<<endl;
                        usage(-1);
                }
                break;
            }
            default://不以'-'開頭,是文件名
                if(ofile_on){//輸出文件名
                    cout<<"file name:"<<pchar<<endl;
                    ofile_name = pchar;
                    ofile_on = false;//復位
                }
                else if(limit_on){//限制值
                    limit_on = false;
                    limit = atoi(pchar);
                    if(limit<0){
                        cerr<<prog_name<<":error:negative value for limit!"<<endl;
                        usage(-2);
                    }
                }
                else{//文件名
                    file_names.push_back(pchar);
                }
                break;
        }
    }
    if(file_names.empty()){
        cerr<<prog_name<<":error:no file for processing!"<<endl;
        usage(3);
    }
    else{
        cout<<(file_names.size() == 1 ? "File":"Files")<<
            " to be processed are the followed:"<<endl;
        for(int i = 0;i < file_names.size();++i){
            cout<<file_names[i]<<"\t"<<endl;
        }
    }
    if(limit != -1){
        cout<<"user-specified limit:"<<limit<<endl;
    }
    if(!ofile_name.empty()){
        cout<<"user-specified ofile:"<<ofile_name<<endl;
    }
    
}
復制代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM