C++ 导入csv时出现分段错误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

我正在生成一个函数importsv(),它接收一个文件名并输出一个二维数组。出于某种原因,每当我使用以下版本的importsv(),编译器都会平稳运行,但可执行文件总是返回“segmentation fault:11”错误

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;
    }