解析文件时 getline 上的分段错误
Segmentation fault on getline while parsing a file
我正在制作一个非常简单的 CSV 格式的文件解析器。编译 运行 很顺利,当我 运行 它时,我遇到了段错误(核心已转储)。唯一打印的行是告诉 "Done" 文件已成功打开的行。所以我的猜测是段错误发生在 while(getline(myfile, line))
.
期间
这是我的代码 (parser.cpp
):
#include "parser.h"
vector<string> str_explode(string const & s, char delim)
{
vector<string> result;
istringstream iss(s);
for (string token; getline(iss, token, delim); )
{
result.push_back(move(token));
}
return result;
}
vector<vector<string>> getTokensFromFile(string fileName)
{
bool verbose = true;
if(verbose)
cout << "Entering getTokensFromFile(" << fileName << ")" << endl ;
/* declaring what we'll need :
* string line -> the line beeing parsed
* ifstream myfile -> the file that name has been given as parameter
* vector <vector <string> > tokens -> the return value
*
* Putting all line into tokens
*/
string line;
ifstream myfile(fileName);
vector< vector<string> > tokens;
if(verbose)
cout << "Opening file " << fileName << " ... ";
if (myfile.is_open())
{
if(verbose)
cout << "Done !" << endl;
while (getline (myfile,line))
{
if(verbose)
cout << "Parsing line '" << line << "'. ";
// If line is blank or start with # (comment)
// then we don't parse it
if((line.length() == 0) || (line.at(0) == '#'))
{
if(verbose)
cout << "Empty or comment, passing.";
continue;
}
else
{
vector <string> tmptokens;
if(verbose)
cout << "Adding token " << tmptokens[0] << " and its values.";
tokens.push_back(tmptokens);
}
cout << endl;
}
}
else
{
cout << "Unable to open file " << fileName << endl;
throw exception();
}
if(verbose)
cout << "Exiting getTokensFromFile(" << fileName << ")" << endl;
return tokens;
}
main.cpp
#include "parser.h"
int main()
{
getTokensFromFile("testfile.csv");
return 0;
}
还有我的testfile.csv
version;1.3
###### SPECIE ######
SpecieID;Value1
VariantID;Value2
####################
##### IDENTITY #####
Name;Value3
DOName;Value4
####################
所有文件都在同一个文件夹中。
你知道我为什么会出现这个段错误吗?
谢谢
这是一个明显的错误,您越界访问向量的元素。访问越界元素是未定义的行为。
else
{
vector <string> tmptokens;
if(verbose)
cout << "Adding token " << tmptokens[0] << " and its values.";
tokens.push_back(tmptokens);
}
因为tmptokens
是空的,所以没有tmptokens[0]
。
如果向量为空,您可以这样做:
else
{
if(verbose)
cout << "Adding new token and its values.";
tokens.push_back({});
}
无需手动创建从 C++11 开始的空向量。
我正在制作一个非常简单的 CSV 格式的文件解析器。编译 运行 很顺利,当我 运行 它时,我遇到了段错误(核心已转储)。唯一打印的行是告诉 "Done" 文件已成功打开的行。所以我的猜测是段错误发生在 while(getline(myfile, line))
.
这是我的代码 (parser.cpp
):
#include "parser.h"
vector<string> str_explode(string const & s, char delim)
{
vector<string> result;
istringstream iss(s);
for (string token; getline(iss, token, delim); )
{
result.push_back(move(token));
}
return result;
}
vector<vector<string>> getTokensFromFile(string fileName)
{
bool verbose = true;
if(verbose)
cout << "Entering getTokensFromFile(" << fileName << ")" << endl ;
/* declaring what we'll need :
* string line -> the line beeing parsed
* ifstream myfile -> the file that name has been given as parameter
* vector <vector <string> > tokens -> the return value
*
* Putting all line into tokens
*/
string line;
ifstream myfile(fileName);
vector< vector<string> > tokens;
if(verbose)
cout << "Opening file " << fileName << " ... ";
if (myfile.is_open())
{
if(verbose)
cout << "Done !" << endl;
while (getline (myfile,line))
{
if(verbose)
cout << "Parsing line '" << line << "'. ";
// If line is blank or start with # (comment)
// then we don't parse it
if((line.length() == 0) || (line.at(0) == '#'))
{
if(verbose)
cout << "Empty or comment, passing.";
continue;
}
else
{
vector <string> tmptokens;
if(verbose)
cout << "Adding token " << tmptokens[0] << " and its values.";
tokens.push_back(tmptokens);
}
cout << endl;
}
}
else
{
cout << "Unable to open file " << fileName << endl;
throw exception();
}
if(verbose)
cout << "Exiting getTokensFromFile(" << fileName << ")" << endl;
return tokens;
}
main.cpp
#include "parser.h"
int main()
{
getTokensFromFile("testfile.csv");
return 0;
}
还有我的testfile.csv
version;1.3
###### SPECIE ######
SpecieID;Value1
VariantID;Value2
####################
##### IDENTITY #####
Name;Value3
DOName;Value4
####################
所有文件都在同一个文件夹中。
你知道我为什么会出现这个段错误吗?
谢谢
这是一个明显的错误,您越界访问向量的元素。访问越界元素是未定义的行为。
else
{
vector <string> tmptokens;
if(verbose)
cout << "Adding token " << tmptokens[0] << " and its values.";
tokens.push_back(tmptokens);
}
因为tmptokens
是空的,所以没有tmptokens[0]
。
如果向量为空,您可以这样做:
else
{
if(verbose)
cout << "Adding new token and its values.";
tokens.push_back({});
}
无需手动创建从 C++11 开始的空向量。