我有一个.csv文件,比方说,1000行和1200列。
如何从所需的列中提取数据,让67 提取到另一列,让我们说890 。 同时从一行让9 到另一行,让我们说789 ,然后用C ++将数据导出为新的csv文件?
我还是初学者,但熟悉for或while循环,我可以读取文件。
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream csvFile;
csvFile.open("../example.csv");
if (csvFile.is_open())
{
string line;
while(getline(csvFile, line))
{
//what to do here
}
}
else {
cout << "Sorry, the file could not be openend." <<endl;
return -1;
}
csvFile.close();
return 0;
}
修改 例如source csv file:
a,1,11,111
b,2,22,222
c,3,33,333
d,4,44,444
假设我们只想从第2列到第3列以及从第2行到第3行,那么结果是一个新的csv文件,如下所示:
2,22
3,33
答案 0 :(得分:0)
我想主要的问题是从给定的列/ raw中捕获数据/变量: 1.需要定义“范围”和它
2使用“value2()”
获取数据关于外观,它不能“同时”:你必须决定程序目标。谢谢!
很抱歉,但是这个代码插入并不常用,所以我放了一个图片:
答案 1 :(得分:0)
有多种方法可以做到这一点。首先想到的是将.csv
文件读入vector<string>
的向量,以便每个行/列值存储在2D数组中,如向量的向量容器。 (例如std::vector<std::vector<string>> array;
)。这样,您就可以使用.csv
和getline
轻松解析您的stringstream
文件,并在','
上分隔。
然后,您可以编写一个提取函数,该函数接受对存储的csv值的引用,并使用基于范围的迭代器对各个向量和字符串迭代向量。此时,只需保留行索引和列索引,并在所需范围内输出所需范围和列之间的行的所有值。一个简单的函数看起来类似于:
void extract (vector<vector<string>>const & array, size_t r1, size_t c1,
size_t r2, size_t c2)
{
size_t ridx = 0; /* row index */
for (auto& row : array) { /* range based row iterator */
size_t cidx = 0; /* column index */
if (r1 <= ridx && ridx <= r2) { /* if in row range */
for (auto& col : row) { /* range based col iterator */
if (c1 <= cidx && cidx <= c2) { /* if in col range */
if (cidx > c1) /* if greater than 1st */
cout << ","; /* output separator */
cout << col; /* output value */
}
cidx++; /* increment col index */
}
cout << "\n"; /* output newline */
}
ridx++; /* increment row index */
if (ridx > r2) /* break if row > r2 */
break;
}
}
您可以让它创建一个字符串的辅助向量,以便进行进一步处理,或者您可以简单地输出值(或写入另一个文件),如上所述。
在一个简短的示例中将各个部分组合在一起,在您的问题中显示的行1,第1列和第2行以及第2列之间读取csv文件的输出,您可以执行以下操作:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using std::ifstream;
using std::cout;
using std::cerr;
using std::string;
using std::stringstream;
using std::vector;
void extract (vector<vector<string>>const & array, size_t r1, size_t c1,
size_t r2, size_t c2)
{
size_t ridx = 0; /* row index */
for (auto& row : array) { /* range based row iterator */
size_t cidx = 0; /* column index */
if (r1 <= ridx && ridx <= r2) { /* if in row range */
for (auto& col : row) { /* range based col iterator */
if (c1 <= cidx && cidx <= c2) { /* if in col range */
if (cidx > c1) /* if greater than 1st */
cout << ","; /* output separator */
cout << col; /* output value */
}
cidx++; /* increment col index */
}
cout << "\n"; /* output newline */
}
ridx++; /* increment row index */
if (ridx > r2) /* break if row > r2 */
break;
}
}
int main (int argc, char **argv) {
string line;
vector<vector<string>> array;
if (argc < 2) {
cerr << "error: insufficient input.\n"
"usage: " << argv[0] << " filename\n";
return 1;
}
ifstream f (argv[1]); /* open file */
if (!f.is_open()) {
perror (("error while opening file " + string(argv[1])).c_str());
return 1;
}
while (getline (f, line)) { /* read each line */
string val; /* string to hold value */
vector<string> row; /* vector for row of values */
stringstream s (line); /* stringstream to parse csv */
while (getline (s, val, ',')) /* for each value */
row.push_back (val); /* add to row */
array.push_back (row); /* add row to array */
}
f.close();
cout << "complete array\n\n";
for (auto& row : array) { /* iterate over rows */
for (auto& val : row) /* iterate over vals */
cout << val << " "; /* output value */
cout << "\n"; /* tidy up with '\n' */
}
cout << "\nextracted array\n\n";
extract (array, 1, 1, 2, 2); /* extract from 1,1 to 2,2 */
return 0;
}
(注意:基于范围的循环是C ++ 11的一项功能,因此将-std=c++11
添加到编译字符串中)
您不必将整个文件读入存储空间。您可以在初始读取行期间轻松保持行数和列数,并使用stringstream
解析列,并仅使用您希望输出的值填充array
,或者只输出值那时,但是通过在函数中封装extract
例程,您可以根据需要对csv文件的多个不同范围进行操作。这完全取决于你。完整读取只是让您可以根据需要输出文件的多个不同部分,而无需在原始文件上多次执行I / O.
示例使用/输出
$ ./bin/iostream_sstream_csv dat/extract.csv
complete array
a 1 11 111
b 2 22 222
c 3 33 333
d 4 44 444
extracted array
2,22
3,33
可能有更多的C ++方法可以包含所需的行和列索引,而不是保留简单的行索引和列索引,但每次都有效。您可以查看distance()
或从向量.begin()
中减去当前迭代器,但是适用于迭代器的限制。好老指数不在乎。
仔细看看,如果您有其他问题,请告诉我。