getline 出错(我相信),在获取管道程序的输入时抛出 std::logic_error
Posted
技术标签:
【中文标题】getline 出错(我相信),在获取管道程序的输入时抛出 std::logic_error【英文标题】:Error with getline (I believe), throwing std::logic_error when getting input for pipe program 【发布时间】:2019-10-31 00:52:14 【问题描述】:我正在为我的 UNIX 和网络编程课程做家庭作业,我必须重写 UNIX 管道 (|) 功能。
我尝试了多种方法,例如更改部分代码无济于事,并使用 GDB 尝试调试代码,但它并没有指向任何地方。我已经做了一些错误检查,包括在用户输入空值时退出程序(循环),但这似乎没有帮助。
// Variable declarations.
char command1[255], command2[255];
char *tok1, *tok2;
string file_path;
int pipefd[2], rs;
// Loop indefinitely.
while(1)
// Get user input and store it.
// command 1
cout << "command1? ";
cin.getline(command1, 255);
// tokenize the command based on space as the delimiter
tok1 = strtok(command1, " ");
// if user typed quit, stop the loop.
if((string)tok1 == "quit") break;
// if user left field blank, error and stop the loop.
if(tok1==NULL) cerr << "pipe: Must enter a command.\n"; break;
// command 2
cout << "command2? ";
cin.getline(command1, 255);
// tokenize the command based on space as the delimiter
tok2 = strtok(command2, " ");
// if user typed quit, stop the loop.
if((string)tok2=="quit") break;
// if user left field blank, error and stop the loop.
if(tok2==NULL) cerr << "pipe: Must enter a command.\n"; break;
...循环在管道和叉子之后结束,所有这些都完成了,缩短到我认为问题所在的地方。
以下错误不断出现,我不知道如何修复它。
command1? ls
command2?厕所
在抛出 'std::logic_error' 实例后调用终止
what(): basic_string::_M_construct null 无效
【问题讨论】:
看起来程序试图从空指针构建std::string
。 strtok
用完令牌或检测到错误时返回 NULL。
那么这是否意味着 command1/command2 在某些时候为空?如果我输入命令,我不确定如何或为什么会发生这种情况。
您的第二个 getline
在应该读入 command2
时读入 command2。
嘿,我能说服你用std::getline
读入std::string
,然后用std::istringstream
解析吗?类似getline(cin, command1); istringstream strm(command1); strm >> tok1;
哦,嘿,如果您使用的是 gdb,这里有一个针对 C++ 异常的 gdb 调试技巧。在 gdb 提示符处运行程序之前,请写入catch throw
,这就像抛出异常的断点一样。我相信你也可以做到catch catch
。
【参考方案1】:
在第二个命令之后,您将第一个命令作为输入 getline。
变化:
cin.getline(command2, 255);
// tokenize the command based on space as the delimiter
tok2 = strtok(command1, " ");
收件人:
cout << "command2? ";
// tokenize the command based on space as the delimiter
cin.getline(command2, 255);
【讨论】:
谢谢!这解决了我的空错误。有趣的是,您错误地做某事如何成为您似乎无法弄清楚的最大问题。 我很高兴能帮上忙!【参考方案2】:哦,是的,您的问题的直接答案是将您的 if( tok2 == NULL )
移动到您的 (string)tok2
演员之上。
您将 char 缓冲区转换为 std::string 只是为了进行比较。
所以我假设您已经包含了字符串标题。这意味着您可以访问读入字符串的 getline。这比 char 缓冲区更容易使用和更安全。然后你已经有了一个字符串。
查看https://en.cppreference.com/w/cpp/string/basic_string/getline 并查看覆盖#2 和示例。
这也将解决您的错误,这是由于 strtok 找不到空格,返回 NULL,并且您试图从 NULL 指针中生成字符串。
【讨论】:
谢谢。我会努力的。我知道并尝试使用两者,但出于某种原因,istream 对我来说更有意义。我明白你的意思,我可能会改变它。 @triglav 哦,你可以使用cin >> mystring
而不是strtok 来打破空格,它会在读入std::string mystring;
时打破空白如果你先读一整行,那么你可以创建一个istringstream 从字符串中读取,就好像它是一个流一样。
@triglav 我添加了第一段,它实际上回答了你的问题。 :-)以上是关于getline 出错(我相信),在获取管道程序的输入时抛出 std::logic_error的主要内容,如果未能解决你的问题,请参考以下文章