代码如下:
#include <string>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <vector>
using namespace std;
const string PROMPT = "prompt> ";
const char PIPE_DEL[3] = "||";
bool checkInput(char []);
bool checkInput(char cmd[]){
string command = cmd;
transform(command.begin(), command.end(), command.begin(), ::tolower);
if (command == "q" || command == "quit")
return true;
else
return false;
}
int main(){
int iteration = 0;
while (true){
char command[1024];
pid_t pid;
cout << '\n' << iteration << '\n';
cout << PROMPT;
cin >> command;
if ( checkInput(command) )
break;
char* token = strtok(command, PIPE_DEL);
vector<string> commands;
commands.push_back(token);
cout << "command 1: " << commands[0] << "\n";
iteration ++;
}
return 0;
}
1)“”被视为定界符! 如果我错了,请纠正我,但唯一被视为定界符的是第二个参数中字符串中的内容。此处不是这种情况,因为我的定界符字符串中没有“”,但实际上是这样。
2)为什么执行命令全都乱七八糟? 如果有两个标记,程序将跳过一些代码。
以下是一些输出:
提示>你好
命令1:你好1
这是预期的。没有与分隔符匹配的字符,然后打印出整个字符串。
提示>你好,世界
命令1:您好
1
提示>命令1:世界
2
这完全是意外的。首先,“”不是分隔符。第二,为什么会跳过cin?为什么打印出第一个分隔符的cout语句在cin之前运行?为什么输入第二个令牌?例如运行以下命令:
提示>你好退出
命令1:您好
1
终止程序(如果cin读取“ q”或“ quit”,则程序终止)。这有点证明cin被忽略了,或者至少没有按我期望的那样工作。 cin应该停止,从控制台读取并将其放入array命令。但是,命令保留了“ quit”,这是预期的,因为strtok()修改了输入字符串,但是应该使用它覆盖。
char命令[1024];
3)最后输出
提示>您好||世界
命令1:您好
1
提示>在抛出
的实例后终止调用'std :: logic_error'what():basic_string :: _ M_construct为null
有效中止
再次“”不是定界符。令牌1应该是“ hello”,令牌2(如果我决定解析它)应该是“世界”。该错误不应该存在。
答案 0 :(得分:2)
有几个问题。
首先,提取器cin>>command;
将在收到的第一个空格处停止。如果您想获得完整的路线,则需要执行以下操作:
cin.getline(command,1024);
然后,如果没有更多输入或出现错误,您可能仍然会遇到问题,因为即使没有收到任何输入,您也将始终执行以下操作。最好的方法是重写循环逻辑,以便循环:
while (cin.getline(command,1024)) {
...
}
然后strtok()
不能按预期使用多个字符。实际上,它期望使用不同的定界符,每个定界符都可以使令牌结尾。但是,输入中令牌的结尾将仅是列表之一。
最后,您只将第一个令牌推入commands
向量中。
备注:使用strtok()并不是最好的主意。更好的选择是在整个代码中使用字符串,并使用算法来查找分隔符,例如like this
答案 1 :(得分:1)
多亏了我的回答,我才得以解决我遇到的问题。这是我所做的:
const string PROMPT = "prompt> ";
const string PIPE_DEL = "||";
bool checkInput(string);
bool checkInput(string command){
transform(command.begin(), command.end(), command.begin(), ::tolower);
if (command == "q" || command == "quit")
return true;
else
return false;
}
vector<string> getCommands(string command){
vector<string> commands;
size_t tokenStart = 0, tokenEnd;
while ( (tokenEnd = command.find(PIPE_DEL, tokenStart)) != string::npos ){
commands.push_back(command.substr(tokenStart, tokenEnd - tokenStart));
tokenStart = tokenEnd + PIPE_DEL.length();
}
commands.push_back(command.substr(tokenStart, command.length()));
return commands;
}
int main(){
int iteration = 0;
while (true){
string command;
pid_t pid;
cout << '\n' << iteration << endl;
cout << PROMPT;
getline(cin, command);
if ( checkInput(command) )
break;
vector<string> commands = getCommands(command);
iteration ++;
}
return 0;
}
与以前一样,我严格使用字符串对象。我还使用字符串类中的find函数来解析定界符,而不是strtok()。最后,cin无法正确解析空间。我将其替换为:
getline(cin, command);
不过,正如@Christophe指出的那样,您也可以使用:
cin.getline(command,1024);
在这种情况下,命令是一个字符数组,而1024是要读取的字符数。