C++ 导入csv时出现分段错误11
我正在生成一个函数importsv(),它接收一个文件名并输出一个二维数组。出于某种原因,每当我使用以下版本的importsv(),编译器都会平稳运行,但可执行文件总是返回“segmentation fault:11”错误C++ 导入csv时出现分段错误11,c++,csv,C++,Csv,我正在生成一个函数importsv(),它接收一个文件名并输出一个二维数组。出于某种原因,每当我使用以下版本的importsv(),编译器都会平稳运行,但可执行文件总是返回“segmentation fault:11”错误 typedef向量矩阵; 矩阵导入SV(字符串文件名) { ifstream myfile(filename);//构造一个流,然后将该流与文件“filename”关联 矩阵内容;//将存储流内容的向量。 int i,j; 而(!myfile.eof()) { 如果(myfi
typedef向量矩阵;
矩阵导入SV(字符串文件名)
{
ifstream myfile(filename);//构造一个流,然后将该流与文件“filename”关联
矩阵内容;//将存储流内容的向量。
int i,j;
而(!myfile.eof())
{
如果(myfile.get()==','){++j;}
else if(myfile.get()='\n'){++i;j=0;}
否则{
内容[i][j]=2;}
}
返回内容;
}
有人能找到错误的来源吗?顺便说一句,我有以下标题:
#include <fstream>
#include <iostream>
#include <array>
#include <vector>
using namespace std;
#包括
#包括
#包括
#包括
使用名称空间std;
您尚未定义内容的大小。因此,默认情况下,它将是0
元素的向量。因此,对操作符[]
的调用将导致segmentatin故障。您将得到“segmentation fault:11”,因为您没有为内容分配内存。
contents[i][j]
只有在contents
中包含某些内容时才会起作用
您可以将读取文件和构建矩阵分为多个部分:
读取一行中的所有数字,并将其视为一行内容
从行中读取数字并将其视为行中的列
这样可以简化程序。这还可以帮助您在出现问题时轻松地隔离问题并加以解决
typedef vector<vector<double> > matrix;
double readNextNumber(std::istream& str)
{
double n = 0.0;
str >> n;
// Skip until we get ',' or '\n'
while (str)
{
int c = str.getc();
if ( c == ',' || c == '\n' || c == EOF )
break;
}
return n;
}
std::vector<double> importRow(std::ifstram& myfile)
{
std::string line;
std::vector<double> row;
// Read a line as a string.
// Then parse the string using std::istringstream.
// When you have finished parsing the line, you know
// you have finished constructing a row of the matrix.
std::getline(myfile, line);
if ( myfile )
{
std::istringstream str(line);
while (str)
{
double n = readNextNumber(str);
if (str)
{
row.push_back(n);
}
}
}
return row;
}
matrix importcsv(string filename)
{
ifstream myfile (filename); //Constructs a stream, and then asssociates the stream with the file "filename"
matrix contents; // Vector which will store the contents of the stream.
while(!myfile.eof())
{
std::vector<double> row = importRow(myfile);
if (myfile)
{
contents.push_back(row);
}
}
return contents;
}
typedef向量矩阵;
双读下一个数字(std::istream和str)
{
双n=0.0;
str>>n;
//跳过,直到得到“,”或“\n”
while(str)
{
int c=str.getc();
如果(c==','| | c=='\n'| | c==EOF)
打破
}
返回n;
}
std::vector importRow(std::ifstram&myfile)
{
std::字符串行;
std::向量行;
//把一行读成字符串。
//然后使用std::istringstream解析字符串。
//当您完成对该行的解析后,您就知道了
//您已经完成了矩阵的一行构造。
std::getline(myfile,line);
如果(我的文件)
{
std::istringstream str(线路);
while(str)
{
双n=readNextNumber(str);
如果(str)
{
行。向后推(n);
}
}
}
返回行;
}
矩阵导入SV(字符串文件名)
{
ifstream myfile(filename);//构造一个流,然后将该流与文件“filename”关联
矩阵内容;//将存储流内容的向量。
而(!myfile.eof())
{
std::vector row=importRow(myfile);
如果(我的文件)
{
内容。向后推(行);
}
}
返回内容;
}
根据其他人的建议,快速修复方法是在将每个值读入数组之前使用resize()
//WARNING: THIS PROGRAM UTILIZES C++11
#include <fstream>
#include <iostream>
#include <array>
#include <vector>
#include <cctype>
#include <thread>
using namespace std;
typedef vector<vector<double> > matrix;
matrix importcsv(string filename)
{
ifstream myfile ("wavelengthtorgb.csv"); //Constructs a stream, and then asssociates the stream with the file "filename".
matrix contents {{0.0}};
char nextchar; double data; int i,j;
while(!myfile.eof())
{
myfile.get(nextchar);
if(nextchar==',')
{
++j;
contents[i].resize(j+1);
cout<<"encountered a comma."<<" contents is now " <<i+1<<" x "<<j+1<<'\n';
}
else if(isspace(nextchar))
{
myfile.get(); //You might not need this line - first run with this line, and if there is an error, delete it, and try again.
++i;
contents.resize(i+1);
j=0;
contents[i].resize(j+1);
cout<<"encountered a carriage return."<<" contents is now " <<i+1<<" x "<<j+1<<'\n';
}
else
{
myfile.unget();
myfile >> data;
contents[i][j]=data;
cout<< "encountered a double."<<" contents("<<i<<','<<j<<")="<<data<<'\n';
}
}
return contents;
}
//警告:此程序使用C++11
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
向量矩阵;
矩阵导入SV(字符串文件名)
{
ifstream myfile(“wavelengthtorgb.csv”);//构造一个流,然后将该流与文件“filename”关联。
矩阵内容{0.0};
char nextchar;双数据;int i,j;
而(!myfile.eof())
{
获取(nextchar);
如果(nextchar==',')
{
++j;
内容[i]。调整大小(j+1);
您的矩阵在哪里获得存储数据的空间?通过标准分配器。您应该再次阅读工作原理。您正在写入0x0矩阵,因此是SEGFULT。我建议您使用content.at(I).at(j)=2;
一旦您这样做了,当您的代码抛出异常并且您发现没有足够的空间用于“矩阵”时,请重新考虑您的算法,并可能查看std::vector::operator[]
可以工作,这可能不是您的想法。矩阵
没有行,因此您的代码调用UB。答案很好,但我不清楚myfile>>行如何“将行作为字符串读取”,因为它在第一次遇到空白时就停止读取。我想您的意思是if(std::getline(myfile,line))
但很难说。@WhozCraig,这就是我的意思。谢谢你指出错误。修复了答案。-1
//WARNING: THIS PROGRAM UTILIZES C++11
#include <fstream>
#include <iostream>
#include <array>
#include <vector>
#include <cctype>
#include <thread>
using namespace std;
typedef vector<vector<double> > matrix;
matrix importcsv(string filename)
{
ifstream myfile ("wavelengthtorgb.csv"); //Constructs a stream, and then asssociates the stream with the file "filename".
matrix contents {{0.0}};
char nextchar; double data; int i,j;
while(!myfile.eof())
{
myfile.get(nextchar);
if(nextchar==',')
{
++j;
contents[i].resize(j+1);
cout<<"encountered a comma."<<" contents is now " <<i+1<<" x "<<j+1<<'\n';
}
else if(isspace(nextchar))
{
myfile.get(); //You might not need this line - first run with this line, and if there is an error, delete it, and try again.
++i;
contents.resize(i+1);
j=0;
contents[i].resize(j+1);
cout<<"encountered a carriage return."<<" contents is now " <<i+1<<" x "<<j+1<<'\n';
}
else
{
myfile.unget();
myfile >> data;
contents[i][j]=data;
cout<< "encountered a double."<<" contents("<<i<<','<<j<<")="<<data<<'\n';
}
}
return contents;
}