CSP201403-3:命令行選項

引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中國計算機學會(CCF)發起的"計算機職業資格認證"考試,針對計算機軟件開發、軟件測試、信息管理等領域的專業人士進行能力認證。認證對象是從事或將要從事IT領域專業技術與技術管理人員,以及高校招考研究生的複試對象。ios

 

  • 問題描述

  請你寫一個命令行分析程序,用以分析給定的命令行裏包含哪些選項。每一個命令行由若干個字符串組成,它們之間剛好由一個空格分隔。這些字符串中的第一個爲該命令行工具的名字,由小寫字母組成,你的程序不用對它進行處理。在工具名字以後可能會包含若干選項,而後可能會包含一些不是選項的參數。app

  選項有兩類:帶參數的選項和不帶參數的選項。一個合法的無參數選項的形式是一個減號後面跟單個小寫字母,"-a" "-b"。而帶參數選項則由兩個由空格分隔的字符串構成,前者的格式要求與無參數選項相同,後者則是該選項的參數,是由小寫字母,數字和減號組成的非空字符串。jsp

  該命令行工具的做者提供給你一個格式字符串以指定他的命令行工具須要接受哪些選項。這個字符串由若干小寫字母和冒號組成,其中的每一個小寫字母表示一個該程序接受的選項。若是該小寫字母后面緊跟了一個冒號,它就表示一個帶參數的選項,不然則爲不帶參數的選項。例如, "ab:m:" 表示該程序接受三種選項,"-a"(不帶參數),"-b"(帶參數), 以及"-m"(帶參數)函數

  命令行工具的做者準備了若干條命令行用以測試你的程序。對於每一個命令行,你的工具應當一直向後分析。當你的工具遇到某個字符串既不是合法的選項,又不是某個合法選項的參數時,分析就中止。命令行剩餘的未分析部分不構成該命令的選項,所以你的程序應當忽略它們。工具

  • 輸入格式

  輸入的第一行是一個格式字符串,它至少包含一個字符,且長度不超過 52。格式字符串只包含小寫字母和冒號,保證每一個小寫字母至多出現一次,不會有兩個相鄰的冒號,也不會以冒號開頭。測試

  輸入的第二行是一個正整數 N(1 ≤ N ≤ 20),表示你須要處理的命令行的個數。spa

  接下來有 N ,每行是一個待處理的命令行,它包括不超過 256 個字符。該命令行必定是若干個由單個空格分隔的字符串構成,每一個字符串裏只包含小寫字母,數字和減號。命令行

  • 輸出格式

  輸出有 N 行。其中第 i 行以"Case i:" 開始,而後應當有剛好一個空格,而後應當按照字母升序輸出該命令行中用到的全部選項的名稱,對於帶參數的選項,在輸出它的名稱以後還要輸出它的參數。若是一個選項在命令行中出現了屢次,只輸出一次。若是一個帶參數的選項在命令行中出現了屢次,只輸出最後一次出現時所帶的參數。orm

  • 樣例輸入

  albw:x 對象

  4

  ls -a -l -a documents -b

  ls

  ls -w 10 -x -w 15

  ls -a -b -c -d -e -l

  • 樣例輸出

  Case 1: -a -l

  Case 2:

  Case 3: -w 15 -x

  Case 4: -a -b

 

  • 源代碼

# include <iostream>

# include <string>

# include <vector>

# include <map>

 

using namespace std;

 

vector<string> split(string &s, const string &seperator);

 

int main(void)

{

    map<string, int> format_map; // 判斷命令選項是否帶參數

    string format_string; // 格式字符串

    int sample_count; // 命令數

    

    cin >> format_string;

    cin >> sample_count;

    

    for (string::size_type i = 0; i != format_string.length(); i++)

    {

        // 若是當前字符是冒號,不作任何處理

        if (format_string[i] == ':')

        {

            continue;

        }

        

        // 選項帶參數,將對應選項的value設爲1

        if (i != format_string.length()-1 && format_string[i+1] == ':')

        {

            string s = "-";

            s = s + format_string[i];

            format_map[s] = 1;

        }

        // 選項不帶參數,將對應選項的value設爲2

        else

        {

            string s = "-";

            s = s + format_string[i];

            format_map[s] = 2;

        }

    }

    

//    // 迭代器遍歷format_map,判斷結果是否正確

//    for (map<string, int>::iterator it = format_map.begin(); it != format_map.end(); it++)

//    {

//        cout << it->first << " " << it->second << endl;

//    }

 

    // cin不會讀入換行,若是這裏不對換行作特殊處理,第一次執行for循環時,getline會讀入以前的換行

    string assist_string;

    getline(cin, assist_string);

    for (int i = 0; i < sample_count; i++)

    {

        map<string, string> output_map; // 最終要輸出的map

        string input_string; // 輸入的一行命令

        getline(cin, input_string);

        vector<string> v = split(input_string, " "); // 調用自定義函數對字符串分割

        for (vector<string>::iterator it = v.begin(); it != v.end(); it++)

        {

            if (it == v.begin())

            {

                continue;    

            }

            

            if (format_map.find(*it) != format_map.end()) // 關鍵字存在,即命令選項存在

            {

                if (format_map[*it] == 1) // 選項帶參數

                {

                    if (it+1 == v.end()) // 本該帶參數的選項沒帶參數

                    {

                        break;

                    }

                    else

                    {

                        output_map[*it] = " " + *(it+1);

                        it++;

                    }

                }

                else // 選項不帶參數

                {

                    output_map[*it] = "";

                }

            }

            else // 關鍵字不存在,也就說命令選項不存在

            {

                break;    

            }

        }

        cout << "Case " << i+1 << ":";

        for (map<string, string>::iterator mit = output_map.begin(); mit != output_map.end(); mit++)

        {

            cout << " " << mit->first << mit->second;

 

        }

        cout << endl;

    }

    

 

    return 0;

}

 

vector<string> split(string &s, const string &seperator)

{

    string::size_type index = 0;

    vector<string> vector_string;

    

    while ((index = s.find(seperator)) != -1)

    {

        string temp = s.substr(0, index);

        vector_string.push_back(temp);

        s = s.substr(index+1, s.length()-index-1);

    }

    if (s.length() > 0)

    {

        vector_string.push_back(s);

    }

    

    return vector_string;

}

相關文章
相關標籤/搜索