CSV数据转换为2D整数数组 [英] CSV data into a 2D array of integers

查看:99
本文介绍了CSV数据转换为2D整数数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个.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"数组的使用,实际上需要vectorrow vectorsstd::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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆