C++ 分段故障核心转储
我试图写一个lexer,当我试图在一个char数组中复制isdigit缓冲区值时,我得到了这个核心转储错误,尽管我对identifier做了同样的事情,但没有得到错误C++ 分段故障核心转储,c++,C++,我试图写一个lexer,当我试图在一个char数组中复制isdigit缓冲区值时,我得到了这个核心转储错误,尽管我对identifier做了同样的事情,但没有得到错误 #include<fstream> #include<iostream> #include<cctype> #include <cstring> #include<typeinfo> using namespace std; int isKeyword(char
#include<fstream>
#include<iostream>
#include<cctype>
#include <cstring>
#include<typeinfo>
using namespace std;
int isKeyword(char buffer[]){
char keywords[22][10] = {"break","case","char","const","continue","default", "switch",
"do","double","else","float","for","if","int","long","return","short",
"sizeof","struct","void","while","main"};
int i, flag = 0;
for(i = 0; i < 22; ++i){
if(strcmp(keywords[i], buffer) == 0)
{
flag = 1;
break;
}
}
return flag;
}
int isSymbol_Punct(char word)
{
int flag = 0;
char symbols_punct[] = {'<','>','!','+','-','*','/','%','=',';','(',')','{', '}','.'};
for(int x= 0; x< 15; ++x)
{
if(word==symbols_punct[x])
{
flag = 1;
break;
}
}
return flag;
}
int main()
{
char buffer[15],buffer1[15];
char identifier[30][10];
char number[30][10];
memset(&identifier[0], '\0', sizeof(identifier));
memset(&number[0], '\0', sizeof(number));
char word;
ifstream fin("program.txt");
if(!fin.is_open())
{
cout<<"Error while opening the file"<<endl;
}
int i,k,j,l=0;
while (!fin.eof())
{
word = fin.get();
if(isSymbol_Punct(word)==1)
{
cout<<"<"<<word<<", Symbol/Punctuation>"<<endl;
}
if(isalpha(word))
{
buffer[j++] = word;
// cout<<"buffer: "<<buffer<<endl;
}
else if((word == ' ' || word == '\n' || isSymbol_Punct(word)==1) && (j != 0))
{
buffer[j] = '\0';
j = 0;
if(isKeyword(buffer) == 1)
cout<<"<"<<buffer<<", keyword>"<<endl;
else
{
cout<<"<"<<buffer<<", identifier>"<<endl;
strcpy(identifier[i],buffer);
i++;
}
}
else if(isdigit(word))
{
buffer1[l++] = word;
cout<<"buffer: "<<buffer1<<endl;
}
else if((word == ' ' || word == '\n' || isSymbol_Punct(word)==1) && (l != 0))
{
buffer1[l] = '\0';
l = 0;
cout<<"<"<<buffer1<<", number>"<<endl;
// cout << "Type is: "<<typeid(buffer1).name() << endl;
strcpy(number[k],buffer1);
k++;
}
}
cout<<"Identifier Table"<<endl;
int z=0;
while(strcmp(identifier[z],"\0")!=0)
{
cout <<z<<"\t\t"<< identifier[z]<<endl;
z++;
}
// cout<<"Number Table"<<endl;
// int y=0;
// while(strcmp(number[y],"\0")!=0)
// {
// cout <<y<<"\t\t"<< number[y]<<endl;
// y++;
// }
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int isKeyword(字符缓冲区[]){
字符关键字[22][10]={“break”、“case”、“char”、“const”、“continue”、“default”、“switch”,
“do”、“double”、“else”、“float”、“for”、“if”、“int”、“long”、“return”、“short”,
“sizeof”、“struct”、“void”、“while”、“main”};
int i,flag=0;
对于(i=0;i<22;++i){
if(strcmp(关键字[i],缓冲区)==0)
{
flag=1;
打破
}
}
返回标志;
}
int isSymbol_点(字符字)
{
int标志=0;
字符符号_putch[]={'、'!'、'+'、'-'、'*'、'/'、'%'、'='、';'、'('、')'、'{'、'}'、'.'};
对于(int x=0;x<15;++x)
{
if(字==符号\u点[x])
{
flag=1;
打破
}
}
返回标志;
}
int main()
{
字符缓冲区[15],缓冲区1[15];
字符标识符[30][10];
字符编号[30][10];
memset(&identifier[0],'\0',sizeof(identifier));
memset(&number[0],'\0',sizeof(number));
字符词;
ifstream fin(“program.txt”);
如果(!fin.is_open())
{
CUT一些一般的提示,可以帮助你完全避免你的撞车原因:设计:
<> LI>因为这是C++,你应该尽可能地引用这里建立的C++数据类型和方案。我知道,在解析器/词法书写方面,不同的东西可能变得非常低,但是至少对于你想要在这里实现的东西,你应该非常感激。尽量避免使用简单的数组。例如,t8_t和/或std::string
- 类似于点1,结果是:总是使用检查边界迭代!你不需要尝试比编译器的优化器更好,至少在这里不需要。一般来说,应该总是避免复制容器大小的信息。对于所述C++容器,此信息总是在数据源侧提供。如果n不可能在非常罕见的情况下(?),使用常量,直接在数据源定义/初始化中声明
- 为变量指定有意义的名称,并尽可能将它们声明为其使用位置的本地变量
- isXXX方法-至少您的方法应该返回布尔值。您永远不会返回0或1以外的值
- 一个有点争议的个人建议是:使用早期返回和中止标准!即使在检查文件读取问题之后,您也可以继续
- 尽量让你的函数保持智能和非样板!使用子例程完成不同的子任务
- 尽量避免在全局范围内使用名称空间!即使没有像UnityBuilds这样的外来构建方案,对于规模更大的项目来说,这也很容易出错
- 数组关键字和符号至少应该是静态常量。优化器将很容易识别这一点,但至少对您快速理解代码有帮助。尝试在此处使用类以可读、自适应、易于修改和可重用的方式组合属于一起的内容。请始终记住,几个月后,您可能想要理解自己的代码,甚至可能是其他开发人员
原因如下(第56行):
inti,k,j,l=0;
您可能认为它将i
,j
,k
和l
初始化为0
,但实际上它只将l
初始化为0
,j
和k
在这里声明,但没有初始化为任何内容。因此,它们包含随机垃圾,如果您将它们作为数组索引使用可能会超出所讨论数组的边界
在这一点上,任何事情都可能发生,换句话说,这是。一个可能的结果,可能发生在你身上,就是你的程序试图访问操作系统没有分配给它的内存,在这一点上它崩溃了(a)
为了具体说明我的意思,请考虑下面的程序:
#包括
无效打印变量(标准::字符串名称,int v)
{
STD:因为这是C++(不是C),为什么不使用<代码> STD::字符串< /代码>?更好地初始化所有的这个代码> int i,k,j,l=0;< /COD>只是为了避免错误访问,已经使用<代码> j<代码>这里>代码>缓冲区[j++ ]=单词,在初始化之前,你可以随意忽略:我建议开始更容易的项目而不是编写(C)词法,因为你似乎还不太精通C++。
i: 32765
j: -113535829
k: 21934
l: 0
int i = 0;
int j = 0;
int k = 0;
int l = 0;