[英]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.