CSV数据转换为2D整数数组 [英] CSV data into a 2D array of integers
问题描述
我有一个.csv文件,该文件在两列多行中都有整数.看起来像这样:
I have a .csv file with integers in two columns and many rows. It looks like this:
A B
1 584 146
2 586 167
. . .
. . .
我想从C ++中的.csv文件创建一个2D整数数组.我已经搜索了数十个网站,但我能获得的所有答案都是字符串.
I want to create a 2D array of integers from this .csv file in C++. I've searched dozens of websites but all of the answers I could get was with strings.
原始数据如下所示:
584,146
586,167
588,189
推荐答案
解决该问题的简单方法是认识到您可以读取整行,然后使用getline
将其作为stringstream
遍历该行.使用','
作为分隔符来分隔值.
The easy way to approach the problem is to recognize that you can read the entire line, and then iterate over the line as a stringstream
using getline
with a ','
as the delimiter to separate the values.
(stringstream
是必需的,您不能在使用getline
读取行本身时简单地将值分开-在行尾没有明显的读取结尾-您只需读取从下一行开始的下一个值)
(stringstream
is required, you can't simply separate the values while reading the line itself with getline
-- there would be no obvious end of read at the end of the line -- you would simply read the next value beginning on the next line)
但是,如果您首先读取该行,创建一个流,然后解析该流,则读取将在流的末尾停止,从而为您提供一种检测行中最后一个值的方法,例如使用向量存储用std::stoi
转换为int
的值,您可以按如下方式填充每个行向量:
However, if you read the line first, create a stream, and then parse the stream, the read stops at the end of the stream providing you a way to detect the last value in a row, e.g. using a vector to store the values converted to int
with std::stoi
, you could fill each row vector as follows:
std::string line, val; /* string for line & value */
...
while (std::getline (f, line)) { /* read each line */
std::vector<int> v; /* row vector v */
std::stringstream s (line); /* stringstream line */
while (getline (s, val, ',')) /* get each value (',' delimited) */
v.push_back (std::stoi (val)); /* add to row vector */
对于"2D"数组的使用,实际上需要vector
为row vectors
或std::vector<std::vector<int>>
.因此,将您的数组声明为:
For your "2D" array use, you actually want a vector
of row vectors
or a std::vector<std::vector<int>>
. So declaring your array as:
std::vector<std::vector<int>> array; /* vector of vector<int> */
您只需将每个行向量v
推回到您的array
中即可完成对行的读取,例如(在上下文中带有声明和循环)
you can complete your read of row into the array simply by pushing each row vector v
back into your array
, e.g. (with declarations and loop in context)
std::string line, val; /* string for line & value */
std::vector<std::vector<int>> array; /* vector of vector<int> */
while (std::getline (f, line)) { /* read each line */
std::vector<int> v; /* row vector v */
std::stringstream s (line); /* stringstream line */
while (getline (s, val, ',')) /* get each value (',' delimited) */
v.push_back (std::stoi (val)); /* add to row vector */
array.push_back (v); /* add row vector to array */
}
剩下的就是访问每个值,以便您可以使用它们.基于范围的循环提供了您所需要的(实际上是一对嵌套的基于范围的循环,一个循环遍历向量,第二个循环遍历值.例如,您可以执行以下操作:
All that remains is accessing each value so you can make use of them. The range-based loop provides just what you need (actually a nested pair of range based loops, one to iterate over the vectors, the second to iterate over values. For example, you could do:
for (auto& row : array) { /* iterate over rows */
for (auto& val : row) /* iterate over vals */
std::cout << val << " "; /* output value */
std::cout << "\n"; /* tidy up with '\n' */
}
将难题的所有部分放在一起,您可以执行类似的操作:
Putting all the pieces of the puzzle together, you could do something similar to:
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
int main (int argc, char **argv) {
std::ifstream f;
if (argc > 1) { /* if argument given */
f.open (argv[1]); /* open file with filename as argument */
if (! f.is_open()) { /* validate file open for reading */
std::cerr << "error: file open failed '" << argv[1] << "'.\n";
return 1;
}
}
else { /* no argument given, error show usage */
std::cerr << "error: insufficient input. <filename> required.\n";
return 1;
}
std::string line, val; /* string for line & value */
std::vector<std::vector<int>> array; /* vector of vector<int> */
while (std::getline (f, line)) { /* read each line */
std::vector<int> v; /* row vector v */
std::stringstream s (line); /* stringstream line */
while (getline (s, val, ',')) /* get each value (',' delimited) */
v.push_back (std::stoi (val)); /* add to row vector */
array.push_back (v); /* add row vector to array */
}
for (auto& row : array) { /* iterate over rows */
for (auto& val : row) /* iterate over vals */
std::cout << val << " "; /* output value */
std::cout << "\n"; /* tidy up with '\n' */
}
}
示例输入文件
输入了以下文件:
$ cat dat/nums.csv
584,146
586,167
588,189
使用/输出示例
它将被解析并存储为整数向量的向量(提供对普通2D数组的访问).
It would be parsed and stored as a vector of integer vectors (providing plain-old 2D array access).
$ /bin/vect2d_strstream dat/nums.csv
584 146
586 167
588 189
仔细研究一下,如果您还有问题,请告诉我.
Look things over and let me know if you still have questions.
这篇关于CSV数据转换为2D整数数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!