读取空格会使解析器崩溃.为什么?
Reading white spaces crashes Parser. Why?
我最终要尝试编写一个shell,所以我需要能够解析命令。我正在尝试将每个单词和特殊符号转换为标记,同时忽略空格。当分隔标记的字符是 |<>但是,一旦我使用单个空格字符,程序就会崩溃。为什么?
我是一名学生,我意识到我想出的分离令牌的方式相当粗糙。我道歉。
#include <iostream>
#include <stdio.h>
#include <string>
#include <cctype>
using namespace std;
#define MAX_TOKENS 10
int main()
{
//input command for shell
string str;
string tokens[MAX_TOKENS] = { "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" };
int token_index = 0;
int start_token = 0;
cout << "Welcome to the Shell: Please enter valid command: " << endl << endl;
cin >> str;
for (unsigned int index = 0; index < str.length(); index++)
{
//if were at end of the string, store the last token
if (index == (str.length() - 1)) tokens[token_index++] = str.substr(start_token, index - start_token + 1);
//if char is a whitespace store the token
else if (isspace(str.at(index)) && (index - start_token > 0))
{
tokens[token_index++] = str.substr(start_token, index - start_token);
start_token = index + 1;
}
//if next char is a special char - store the existing token, and save the special char
else if (str[index] == '|' || str[index] == '<' || str[index] == '>' || str[index] == '&')
{
//stores the token before our special character
if ((index - start_token != 0)) //this if stops special character from storing twice
{
//stores word before Special character
tokens[token_index++] = str.substr(start_token, index - start_token);
}
//stores the current special character
tokens[token_index++] = str[index];
if (isspace(str.at(index + 1))) start_token = index + 2;
else start_token = index + 1;
}
}
cout << endl << "Your tokens are: " << endl;
for (int i = 0; i < token_index; i++)
{
cout << i << " = " << tokens[i] << endl;
}
return 0;
}
几件事:
- 检查
token_index
是否小于MAX_TOKENS
,然后在每次增量后再次使用它,否则会出现缓冲区溢出。如果将tokens
更改为std::vector
则可以使用at()
语法作为安全网。 - 表达式
index - start_token
的类型为unsigned int
,因此它永远不会小于0
。相反,你应该把index > start_token
作为你的测试。 - 如果超出范围
index
str.at(index)
会引发异常。但是,您永远不会发现异常;根据您的编译器,这可能看起来像程序崩溃。将main()
的代码包装在try...catch(std::exception &)
块中。
最后,这是一个很长的镜头,但为了完整起见,我会提到它。最初在C89中,isspace
和其他is
函数必须采用非否定参数。它们的设计使编译器可以通过数组查找来实现它们,因此传入具有负值的带符号字符会导致未定义的行为。 我不完全确定这是否在各种更高版本的 C 和 C++ 中被"修复",但即使标准要求这样做,也可能有一个编译器仍然不喜欢接收负字符。 若要从代码中消除这种情况,请使用isspace( (unsigned char)str.at(index) )
,甚至更好的是,使用 C++ 语言环境接口。
相关文章:
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- 为什么引用传递会导致此崩溃(C++)
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 为什么要增加导致崩溃的指针
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 为什么当我尝试搜索双链表中第一个数据条目之外的数据时,程序崩溃了?
- 为什么从文件获取图标时应用程序有时会崩溃?
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- 您好,我实际上想了解以下代码.有人可以详细说明代码它到底在做什么吗?为什么它会在第 31 行崩溃
- 为什么vector::eras似乎会导致崩溃?
- 为什么我的结构在包含字符串时崩溃?
- 为什么在同一条件变量上使用多个互斥锁会使此代码崩溃?
- C++程序崩溃.为什么?
- 类似的代码.一个工作,一个崩溃.为什么?
- 读取空格会使解析器崩溃.为什么?
- 试图在C++中打印变量int会导致它崩溃.为什么?
- 如果程序包含以下代码,则可能会崩溃.为什么
- 递归二叉搜索实现崩溃.为什么