以下是代码:
#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)为什么执行命令都不正常?如果有两个标记,程序将跳过一些代码。
以下是一些输出:
prompt>你好 命令1:你好 1
这是意料之中的。该分隔符中没有匹配的字符,然后打印出整个字符串。
prompt>你好世界 命令1:你好 1 prompt>命令1: world 2
这完全出乎意料。首先,“”不是分隔符。第二,为什么cin被跳过?为什么正在打印第一个分隔符的cout语句在cin之前运行?为什么输入是第二个令牌?例如,运行以下命令:
prompt> hello退出 命令1:你好 1
终止程序(如果cin读取“q”或“退出”,则程序终止)。这证明cin被忽视了,或者至少不像我预期的那样起作用了。cin应该停止,从控制台读取,并将其放入数组命令中。然而,由于strtok()修改了输入字符串,所以命令保存“退出”,但是这应该被覆盖。
char command1024;
3)最后输出
prompt> hello = world 命令1:你好 1 的实例后调用prompt>终止 'std::logic_error‘what():basic_string::_M_construct null not 有效中止
再说一遍,“”不是分隔符。令牌1应该是"hello“令牌2(如果我决定解析它)应该是”world“。这个错误不应该存在。
发布于 2018-09-23 20:49:29
多亏了我的回答,我才能解决我所遇到的问题。以下是我所做的:
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;
}和以前一样,这里有字符数组,我严格地使用字符串对象。我还使用string类中的find函数来解析分隔符,而不是strtok()。最后,cin不能正确地解析空间。我把它换成了:
getline(cin, command);但是,正如@Christophe所指出的,您也可以使用:
cin.getline(command,1024);在这种情况下,命令是一个字符数组,而1024是要读取的字符数。
发布于 2018-09-23 20:09:33
有几个问题。
首先,提取器cin>>command;将在接收到的第一个空格处停止。如果你想得到一个完整的队伍,你需要做:
cin.getline(command,1024);然后,如果没有更多的输入或出现错误,您可能仍然面临问题,因为您总是执行以下内容,即使没有收到任何输入。最好的方法是重写循环逻辑,以便循环:
while (cin.getline(command,1024)) {
...
}那么strtok()就不会像您所期望的那样处理多个字符。实际上,它需要不同的分隔符,每个分隔符都可以作为标记的结尾。但是,您输入的令牌的末尾将仅为列表之一。
最后,您只将第一个令牌推到commands向量中。
备注:使用strtok()不是最好的主意。一个更好的选择是在代码中使用字符串,并使用算法查找分隔符,例如https://ideone.com/JQjU1T。
https://stackoverflow.com/questions/52469415
复制相似问题