试题编号: 201403-3
试题名称: 命令行选项
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
请你写一个命令行分析程序,用以分析给定的命令行里包含哪些选项。每个命令行由若干个字符串组成,它们之间恰好由一个空格分隔。这些字符串中的第一个为该命令行工具的名字,由小写字母组成,你的程序不用对它进行处理。在工具名字之后可能会包含若干选项,然后可能会包含一 些不是选项的参数。
选项有两类:带参数的选项和不带参数的选项。一个合法的无参数选项的形式是一个减号后面跟单个小写字母,如"-a" 或"-b"。而带参数选项则由两个由空格分隔的字符串构成,前者的格式要求与无参数选项相同,后者则是该选项的参数,是由小写字母,数字和减号组成的非空字符串。
该命令行工具的作者提供给你一个格式字符串以指定他的命令行工具需要接受哪些选项。这个字符串由若干小写字母和冒号组成,其中的每个小写字母表示一个该程序接受的选项。如果该小写字母后面紧跟了一个冒号,它就表示一个带参数的选项,否则则为不带参数的选项。例如, “abⓂ️” 表示该程序接受三种选项,即"-a"(不带参数),"-b"(带参数), 以及"-m"(带参数)。
命令行工具的作者准备了若干条命令行用以测试你的程序。对于每个命令行,你的工具应当一直向后分析。当你的工具遇到某个字符串既不是合法的选项,又不是某个合法选项的参数时,分析就停止。命令行剩余的未分析部分不构成该命令的选项,因此你的程序应当忽略它们。
输入格式
输入的第一行是一个格式字符串,它至少包含一个字符,且长度不超过 52。格式字符串只包含小写字母和冒号,保证每个小写字母至多出现一次,不会有两个相邻的冒号,也不会以冒号开头。
输入的第二行是一个正整数 N(1 ≤ N ≤ 20),表示你需要处理的命令行的个数。
接下来有 N 行,每行是一个待处理的命令行,它包括不超过 256 个字符。该命令行一定是若干个由单个空格分隔的字符串构成,每个字符串里只包含小写字母,数字和减号。
输出格式
输出有 N 行。其中第 i 行以"Case i:" 开始,然后应当有恰好一个空格,然后应当按照字母升序输出该命令行中用到的所有选项的名称,对于带参数的选项,在输出它的名称之后还要输出它的参数。如果一个选项在命令行中出现了多次,只输出一次。如果一个带参数的选项在命令行中出 现了多次,只输出最后一次出现时所带的参数。
样例输入
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
需要注意的几点问题:
1、将输入的一行字符串 分割成若干单独的字符串:
getline接收 ,strtok函数分割 注意用法(参考:https://blog.csdn.net/sxy19930313/article/details/78548174)
2、有参选项没给参数时,是错误的
3、指针判断为空的问题
#include<map>
#include<string>
#include<iostream>
#include<string.h>
//#include<bits/stdc++.h>
using namespace std;
int main() {
string str,s,s2;
int i, j, n, k, flag,x;
char s1[256];
char f;
map<char, int> mp;
map<char, string> m;
cin >> str;
cin >> n;
for (i = 0; i < str.length(); i++)
{
if (str[i] != ':'&&str[i+1] == ':')
mp.insert(pair<char, int>(str[i], 1)); //带参选项标记为1
else if(str[i]!=':')
mp.insert(pair<char, int>(str[i], 2));
}
cin.get(); //接受第一个回车符
for (i = 0; i < n; i++)
{
s.clear();
m.clear();
flag = 0;
getline(cin, s);
memset(s1, '\0', sizeof(s1)); //清空char数组s1
//将输入的一行字符串 分割成若干单独的字符串
strcpy(s1, s.c_str()); // c_str()返回的是一个临时指针,不能直接复制
char *p;
p = strtok(s1, " "); //strtok函数只能处理char型 所以要把输入的string字符串复制到char型数组中
while ( p ) { //或直接 while(p)
p = strtok(NULL," "); //注意 这时要用NULL 双引号中可用多种分隔符
if (NULL == p) //为什么没这步就判断不了正常结束的情况 很奇怪
break;
else if (*p == '-' && mp[*(++p)] && *(++p) == NULL)
{
if (mp[*(--p)] == 1)//此处不判断只有90分
{
f = *p;
if (p = strtok(NULL, " "))
{
s2 = p;
if (m.count(f) > 0) //count函数用于统计key值在map中出现的次数,map的key不允许重复,因此如果key存在返回1,不存在返回0
m[f] = s2; //没有直接判断key值是否在map中存在的函数
else
m.insert(pair<char, string>(f, s2));
}
else
break;
}
else
{
m.insert(pair<char, string>(*p, "N"));
}
}
else
break;
}
//遍历输出m容器中的元素
cout << "Case " << i + 1 << ": ";
for (map<char, string>::iterator it = m.begin(); it != m.end(); it++)
{
cout << '-' <<(*it).first <<' ';
if ((*it).second != "N")
cout << (*it).second << ' ';
}
cout << endl;
}
}