C ++:向向量向量添加行

时间:2017-09-21 21:28:40

标签: c++ csv vector

我试图在C ++中模仿R中的一些数据帧功能,即从CSV文件读取到矩阵并添加/删除行。 CSV文件中的行数可以是任何值,但列数及其数据类型是固定的。所以它不应该是太通用的(即列的可变数量的列或可变数据类型)。我已经能够创建一个基本程序,将数据读取到字符串向量的矢量。

#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

using vec = vector<string>;
using matrix = vector<vec>;


matrix readCSV(string filename)
{
   char separator = ',';
   matrix result;
   string row, item;

   ifstream in(filename);
   while(getline(in, row))
   {
      vec R;
      stringstream ss(row);
      while(getline(ss, item, separator))   R.push_back( item );
      result.push_back(R);
   }
   in.close();
   return result;
}



void printMatrix(const matrix &M)
{
   for(vec row : M)
   {
      for (string s:row)    cout << setw( 12 ) << left << s << " ";
      cout << '\n';
   }
}



void deleteRow(matrix &M, int row)
{
   if(row < M.size())    M.erase( M.begin() + row );
}



void deleteCol(matrix &M, int col)
{
   for(vec &row : M)    if ( col < row.size() )     row.erase( row.begin() + col );
}



void edit( matrix &M, int i, int j, string value )
{
   if (i < M.size() && j < M[i].size())     M[i][j] = value;
}



int main()
{
   matrix pets = readCSV( "pets.csv" );
   printMatrix( pets );

   cout << "\n\n";

   deleteRow( pets, 3 );
   deleteCol( pets, 3 );
   edit( pets, 1, 2, "12" );
   printMatrix( pets );
}

pets.csv:

Animal,Name,Age,Food,Owner,Notes
Dog,Fido,6,Chewies,R. Smith,Barks
Cat,Fluffy,8,Whiskers,M. Jones,Miaows
Hamster,Giles,2,Scratchies,A. Green 
Snake,Hissie,3,Mice,Bob

输出:

Animal       Name         Age          Food         Owner        Notes        
Dog          Fido         6            Chewies      R. Smith     Barks        
Cat          Fluffy       8            Whiskers     M. Jones     Miaows       
Hamster      Giles        2            Scratchies   A. Green     
Snake        Hissie       3            Mice         Bob          


Animal       Name         Age          Owner        Notes        
Dog          Fido         12           R. Smith     Barks        
Cat          Fluffy       8            M. Jones     Miaows       
Snake        Hissie       3            Bob

主要问题是所有列都具有相同的数据类型(在本例中为string)。我应该做哪些修改来允许不同数据类型的列(例如,在这种情况下,age列应该是int和其余的字符串)? 另外,如何在矩阵中添加新的行或列?

1 个答案:

答案 0 :(得分:1)

如果每列都是不同的类型,则意味着您应该有一个对象向量,而不是向量向量。您没有处理表格数据,而是处理记录

类似的东西:

struct Pet
{
    std::string animal;
    std::string name;
    unsigned int age;
    std::string food;
    std::string owner;
    std::string notes;
};

// Later
std::vector<Pet> pets;

在这个模型中:

  

如何在矩阵中添加新行?

将新的Pet对象推入向量。

  

如何在矩阵中添加新列?

将新数据成员添加到Pet类型。

  

如何将stringstream中的数据读入struct对象

使用辅助函数进行阅读:

Pet read_pet(std::string const &row)
{
    Pet pet;

    std::istringstream ss{row};

    std::getline(ss, pet.animal, ',');
    std::getline(ss, pet.name, ',');
    ss >> pet.age;
    ss.ignore(std::numeric_limits<std::streamsize>::max(), ',');
    std::getline(ss, pet.food, ',');
    std::getline(ss, pet.owner, ',');
    std::getline(ss, pet.notes, ',');

    return pet;
}
  

然后将其推入矩阵?

while(getline(in, row))
{
    result.emplace_back(read_pet(row));
}