【问题标题】:is there any ways to get specific column from csv file?有什么方法可以从 csv 文件中获取特定的列?
【发布时间】:2020-04-02 09:17:18
【问题描述】:

大家好,我刚开始学习如何使用 c++ 进行 csv 文件管理,目前此代码有效。它可以打印出“数学”列。

但只有当我使用 getline(ss,#any column variable#, ',') 分配每一列时 然后我打印出我想要的列。但如果我将它用于一个大列表,让我们说一个包含大约 100 列的 csv 文件。那么,我该如何简化呢?或者有什么方法可以让我只获取特定的列而不将每一列分配/解析给每个变量?假设从 100 列开始,我只希望第 47 列有任何可能的名称?或者我可以通过它的名称来获取列?

谢谢。

【问题讨论】:

  • 请不要显示文本图像,尤其是所有代码。将文本 as text 复制粘贴到问题中。
  • 只要你写代码,一切皆有可能。将每一行读入std::vector<std::string>,然后您可以对其进行索引。如果您随后还将第一行读入std::map<std::string, int>,您可以按名称抓取列。
  • 至于你的问题,我建议你学习structuresclasses,以及标准容器(比如std::vector)。请记住,您可以在结构中包含一个向量(例如数据字段)。
  • 是的,字符串向量是你最好的选择。然后你可以选择索引为 46 的元素。如果你附上 csv 我可以看看它
  • @Someprogrammerdude 好的,先生。下次我会正确地做。谢谢你的建议,对我的错误深表歉意。呵呵

标签: c++ csv getline


【解决方案1】:

这是一个快速的 [工作] 示例。

  • 第一部分读入表格。
  • 第二部分(fin.close() 之后)让您选择要打印的内容(或您选择的任何内容)。
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>  //std::find
using namespace std;
int main(int argc, char** argv)
{
   ifstream fin("filename");
   string line;
   int rowCount=0;
   int rowIdx=0; //keep track of inserted rows

   //count the total nb of lines in your file
   while(getline(fin,line)){
      rowCount++;
   }

   //this will be your table. A row is represented by data[row_number].
   //If you want to access the name of the column #47, you would
   //cout << data[0][46]. 0 being the first row(assuming headers)
   //and 46 is the 47 column.
   //But first you have to input the data. See below.
   vector<string> data[rowCount];

   fin.clear(); //remove failbit (ie: continue using fin.)
   fin.seekg(fin.beg); //rewind stream to start

   while(getline(fin,line)) //for every line in input file
   {
      stringstream ss(line);  //copy line to stringstream
      string value;
      while(getline(ss,value,’,’)){       //for every value in that stream (ie: every cell on that row)
         data[rowIdx].push_back(value);//add that value at the end of the current row in our table
      }
      rowIdx++;   //increment row number before reading in next line
   }
}
   fin.close();


   //Now you can choose to access the data however you like.
   //If you want to printout only column 47...

   int colNum=47;  //set this number to the column you want to printout

   for(int row=0; row<rowCount; row++)
   {
      cout << data[row][colNum] << "\t";  //print every value in column 47 only
   }
   cout << endl


   return 0;
}

编辑:添加这个以获得更完整的答案。

要按名称搜索列,请将最后一个 for 循环替换为此 sn-p


   //if you want to look up a column by name, instead of by column number...
   //Use find on that row to get its column number.
   //Than you can printout just that column.
   int colNum;
   string colName = "computer science";

   //1.Find the index of column name "computer science" on the first row, using iterator
   //note: if "it == data[0].end()", it means that that column name was not found 
   vector<string>::iterator it = find(data[0].begin(), data[0].end(),colName);  

   //calulate its index (ie: column number integer)  
   colNum = std::distance(data[0].begin(), it);   

   //2. Print the column with the header "computer science"
   for(int row=0; row<rowCount; row++)
   {
      cout << data[row][colNum] << "\t";  //print every value in column 47 only
   }
   cout << endl

   return 0;
}


【讨论】:

  • 谢谢你,这个例子和你的解释很有帮助。这个可以做我想做的,现在我也在尝试研究其他人给出的其他解决方案。呵呵。
  • 太好了!很高兴我能帮上忙。也请查看我的编辑,我添加了一些代码来专门按名称查看列。
  • 对不起。对于从列名进行的搜索不起作用,它给了我没有匹配的函数来调用查找向量.....
  • 哎呀,将此添加到您的包含中 #include &lt;algorithm&gt; 抱歉
  • 如果您对此有任何其他问题,请告诉我
【解决方案2】:

或者有什么方法可以让我只获取特定的列而不将每一列分配/解析给每个变量?

使用 CSV 格式来避免读取每一列并不是很实用,所以你真正想要做的基本上只是丢弃你不想要的列,很多就像你已经在做的那样。

要使其适用于未知数量的列,您可以读入std::vector,它基本上是一个动态大小的数组,对于这种情况非常有用。

std::vector<std::string> read_csv_line(const std::string &line)
{
    std::vector<std::string> ret;
    std::string val;
    std::stringstream ss(line);
    while (std::getline(ss, val, ','))
        ret.push_back(std::move(val));
    return ret;
}

...
std::getline(is, line);
auto row = read_csv_line(line);
if (row.size() > 10) // Check each row is expected size!
  std::cout << row[0] << ", " << row[10] << std::endl;
else std::cerr << "Row too short" << std::endl;

然后您可以访问所需的特定列。

或者我可以通过它的名称来获取列?

假设您的 CSV 文件有一个标题行,您可以将其读入std::unordered_map&lt;std::string, size_t&gt;,其中值是列索引。或者像std::vectorstd::find


请注意,单个std::getline 无法处理引用值和其他一些可能的 CSV 功能。

【讨论】:

    猜你喜欢
    • 2018-07-05
    • 2020-05-11
    • 2016-08-22
    • 1970-01-01
    • 2013-09-24
    • 2016-05-16
    • 2020-04-11
    • 2022-12-05
    • 2013-09-24
    相关资源
    最近更新 更多