导入csv时出现分段错误11错误

时间:2014-06-09 19:51:31

标签: c++ csv

我正在创建一个函数importcsv(),它接受一个文件名并输出一个2D数组。出于某种原因,每当我使用以下版本的importcsv()时,编译器都会顺利运行,但可执行文件始终返回一个"分段错误:11"错误。

typedef vector<vector<double> > matrix;

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.
   int i, j;
   while(!myfile.eof())
   {
       if(myfile.get()==','){++j;}
       else if(myfile.get()=='\n'){++i; j=0;}
       else{
        contents[i][j]=2;}
   }
   return contents;
}

有人能找到错误的来源吗?顺便说一下,我有以下标题:

#include <fstream>
#include <iostream>
#include <array>
#include <vector>
using namespace std;

3 个答案:

答案 0 :(得分:2)

由于您尚未为contents分配内存,因此您收到“segment fault:11”。 contents[i][j]仅在contents包含内容时才有效。

您可以将文件的读取和构建矩阵分成不同的部分:

  1. 读取一行中的所有数字并将其视为一行contents
  2. 从行中读取一个数字并将其视为一行的列。
  3. 这样,程序可以简化。这也有助于您在有问题时轻松隔离问题并进行修复。

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

答案 1 :(得分:0)

您尚未定义contents的大小。因此,默认情况下,它将是vector 0元素。因此,对operator[]的调用将导致分段错误。

答案 2 :(得分:-1)

在这里实现其他人的建议,快速解决方法是在将每个值读入数组之前使用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;
}