简体   繁体   English

C ++将CSV文件的一列写入向量

[英]C++ Writing a column of a CSV file into a vector

I have a CSV file with a bunch of columns, but I only need the information for the 11th column.我有一个包含一堆列的 CSV 文件,但我只需要第 11 列的信息。 How do I read through each line and skip to the 11th column in each line?如何通读每一行并跳到每行的第 11 列? I'm struggling to find clear information on how to read files in c++.我正在努力寻找有关如何在 C++ 中读取文件的明确信息。 This is what I have so far:这是我到目前为止:

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

std::string readStock(std::string fileName){
   std::vector<std::string> ticker; //create vector
   std::ifstream f(fileName, std::ios::in|std::ios:: binary|std::ios::ate);
   std::string finalString = "";
   if(f.is_open()){
     std::string str;
     std::getline(f,str); //skip the first row
     while(std::getline(f,str)){ //read each line
       std::istringstream s(str);  //stringstream to parse csv
       std::string val;  //string to hold value
       for(int i=1;i<=10;++i){ //skips everything until we get to the
column that we want
         while(std::getline(s,val, ',')){
         }
       std::getline(s,val,',');
       ticker.push_back(val);
     }
     f.close();

     finalString = ticker.front();
   }
}
   else{
     finalString="Could not open the file properly.";
   }
   return finalString;
}
int main(){
   std::string st;
   st=readStock("pr.csv");
   std::cout<<st<<std::endl;
   return 0;
}


There is a very simple solution for your problem.您的问题有一个非常简单的解决方案。

You define a proxy class that reads one complete line, splits it into ALL tokens, using the dedicated functionality of the std::regex_token_iterator and then extracts the 11th element.您定义了一个代理类,该类读取一个完整的行,使用std::regex_token_iterator的专用功能将其拆分为所有标记,然后提取第 11 个元素。

Using this proxy mechanism, you can use the std::istream_iterator to read the complete file, column 11, into a std::vector .使用此代理机制,您可以使用std::istream_iterator将完整文件(第 11 列)读入std::vector For that we use the range constructor of the std::vector .为此,我们使用std::vector的范围构造函数。

The result is a simple and short one-liner.结果是一个简单而短的单线。

Please see:请参见:

#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <regex>
#include <iterator>
#include <algorithm>

std::regex delimiter{ "," };
constexpr size_t targetColumn = 10U; // Target column is eleven


struct String11 {   // Proxy for the input Iterator

    // Overload extractor. Read a complete line
    friend std::istream& operator>>(std::istream& is, String11& s11) { 

        // Read a complete line
        if (std::string line{}; std::getline(is, line)) {

            // Split it into tokens
            std::vector token(std::sregex_token_iterator(line.begin(), line.end(), delimiter, -1), {});
            // We only need one column
            if (targetColumn < token.size()) {
                // Get column 11
                s11.result = token[targetColumn];
            }
        }
        return is; 
    }

    // Cast the type 'String11' to std::string
    operator std::string() const { return result; }

    // Temporary to hold the resulting string
    std::string result{};
};

int main() {

    // Open CSV fíle
    if (std::ifstream csvFile{ "pr.csv" }; csvFile) {

        // Read complete CSV file and get column 11 of each line
        std::vector col11(std::istream_iterator<String11>(csvFile), {});

        // Show output. Show all columns 11
        std::copy(col11.begin(), col11.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
    }
    return 0;
}

EDIT:编辑:

For having output with doubles.用于双打输出。

We just change one line in the cast operator in the proxy.我们只更改代理中的 cast 运算符中的一行。 That's all.就这样。

Even in main, there is no change in the read operatrion necessary.即使在 main 中,也没有必要更改读取操作。 Through CTAD, the vector will be of type double .通过 CTAD,向量将是double类型。

Please see:请参见:

#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <regex>
#include <iterator>
#include <algorithm>

std::regex delimiter{ "," };
constexpr size_t targetColumn = 10U; // Target column is eleven


struct String11 {   // Proxy for the input Iterator

    // Overload extractor. Read a complete line
    friend std::istream& operator>>(std::istream& is, String11& s11) { 

        // Read a complete line
        if (std::string line{}; std::getline(is, line)) {

            // Split it into tokens
            std::vector token(std::sregex_token_iterator(line.begin(), line.end(), delimiter, -1), {});
            // We only need one column
            if (targetColumn < token.size()) {
                // Get column 11
                s11.result = token[targetColumn];
            }
        }
        return is; 
    }

    // Cast the type 'String11' to double
    operator double() const { return std::stod(result); }

    // Temporary to hold the resulting string
    std::string result{};
};

int main() {

    // Open CSV fíle
    if (std::ifstream csvFile{ "r:\\pr.csv" }; csvFile) {

        // Read complete CSV file and get column 11 of each line
        std::vector col11(std::istream_iterator<String11>(csvFile), {});

        // Show output. Show all columns 11
        std::copy(col11.begin(), col11.end(), std::ostream_iterator<double>(std::cout, "\n"));
    }
    return 0;
}

Output needs to adapted as well.输出也需要适应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM