简体   繁体   English

csv 文件中 C++ 中多维数组的总和

[英]Sum of Multidimensional array in C++ from csv file

Would anyone be able to help me, I am trying to make a C++ program which reads values from csv file and prints them(there are going to be three 4 rows, 3 columns).谁能帮助我,我正在尝试制作一个 C++ 程序,该程序从 csv 文件中读取值并打印它们(将有三个 4 行 3 列)。 I want to know how can I add the rows (like the sum of the first row =? the sum of second-row =?...)我想知道如何添加行(例如第一行的总和=?第二行的总和=?...)

The matrix looks like this:矩阵如下所示:

在此处输入图像描述

And my program looks like:我的程序看起来像:

#include <iostream>
#include <fstream>

using namespace std;

int main() {
    
    ifstream sumCol;
    sumCol.open("Col.csv");
    
    string line;
    int sum;
    
    cout << "The entered matrix: " << endl;
    while(sumCol.good()){
        string line;
        getline(sumCol, line, ',');
        cout << line << "  ";
    }

    while(sumCol.good()){
        getline(sumCol, line, ',');
        int i = stoi(line);
        cout << endl; 
        cout << i;
    }
    
    
  while(getline(sumCol, line, ',')){
        int i = stoi(line);
        sum = sum + i;
        
        getline(sumCol, line, ',');
        i = stoi(line);
        sum = sum + i;
        
        getline(sumCol, line);
        i = stoi(line);
        sum = sum + i;
    }
    
    cout << sum << endl;
    
    return 0;
}

Next try.下次试试。 Very simple answer with just basic constructs.非常简单的答案,只有基本结构。

12 statements. 12 个陈述。 But 2 for loops, nested and hardcoded magic numbers for rows and columns.但是 2 个 for 循环,行和列的嵌套和硬编码幻数。

Please see the below well commented source code:请参阅以下注释良好的源代码:

#include <iostream>
#include <fstream>

int main() {

    // Open file 
    std::ifstream csv("col.csv");

    // and check, if it could be opened
    if (csv) {

        // Now the file is open. We have 3 rows and 4 columns
        // We will use 2 nested for loops, one for the rows and one for the columns

        // So, first the rows
        for (int row = 0; row < 3; ++row) {

            // Every row has a sum
            int sumForOneRow = 0;

            // And every row has 4 columns. Go through all coulmns of the current row.
            for (int col = 0; col < 4; ++col) {

                // Read an integer value from the current line
                int integerValue;
                csv >> integerValue;

                // Show it on the screen
                std::cout << integerValue << ' ';

                // Update the sum of the row
                sumForOneRow = sumForOneRow + integerValue;
            }
            // Now, the inner for loop for the 4 columns is done. Show sum to user
            std::cout << " --> " << sumForOneRow << '\n';

            // Line activities are done now for this line. Go on with next line
        }

    }
    else std::cerr << "\n*** Error: Could not open 'col.csv'\n";
    return 0;
}

Third try.第三次尝试。

Obviously the matrix, shown in the question, does not reflect the real data.显然,问题中显示的矩阵并不反映真实数据。 The real data might look like that:真实数据可能如下所示:

9, 1, 2, 4
9, 2, 8, 0 
3, 3, 3, 3

Without using std::getline we can do like the below:在不使用std::getline的情况下,我们可以执行以下操作:

#include <iostream>
#include <fstream>

int main() {

    // Open file 
    std::ifstream csv("r:\\col.csv");

    // and check, if it could be opened
    if (csv) {

        // Now the file is open. We have 3 rows and 4 columns
        // We will use 2 nested for loops, one for the rows and one for the columns

        // So, first the rows
        for (int row = 0; row < 3; ++row) {

            // Every row has a sum
            int sumForOneRow = 0;

            // And every row has 4 columns. Go through all coulmns of the current row.
            for (int col = 0; col < 4; ++col) {

                // Read an integer value from the current line
                int integerValue;
                char c; // for the comma

                // The last value, the value in column 3 (We start counting with 0) is not followed by a comma
                // Therefore we add special treatment for the last column
                if (col == 3)
                    csv >> integerValue; // Read just the value
                else
                    csv >> integerValue >> c; // Read value and comma

                // Show it on the screen
                std::cout << integerValue << ' ';

                // Update the sum of the row
                sumForOneRow = sumForOneRow + integerValue;
            }
            // Now, the inner for loop for the 4 columns is done. Show sum to user
            std::cout << " --> " << sumForOneRow << '\n';

            // Line activities are done now for this line. Go on with next line
        }

    }
    else std::cerr << "\n*** Error: Could not open 'col.csv'\n";
    return 0;
}

4th try.第四次尝试。 Based on the evolution of this thread and the request of the OP to use std::getline基于此线程的演变和 OP 使用std::getline的请求

#include <iostream>
#include <fstream>
#include <string>

int main() {

    // Open file 
    std::ifstream csv("r:\\col.csv");

    // and check, if it could be opened
    if (csv) {

        // Now the file is open. We have 3 rows and 4 columns
        // We will use 2 nested for loops, one for the rows and one for the columns

        // So, first the rows
        for (int row = 0; row < 3; ++row) {

            // Every row has a sum
            int sumForOneRow = 0;

            // And every row has 4 columns. Go through all coulmns of the current row.
            for (int col = 0; col < 4; ++col) {

                // Read a substring up to the next comma or end of line
                std::string line;

                // Special handling for last column. This is not followed by a comma
                if (col == 3)
                    std::getline(csv, line);
                else
                    std::getline(csv, line, ',');

                // Convert string to line
                int integerValue = std::stoi(line);

                // Show it on the screen
                std::cout << integerValue << ' ';

                // Update the sum of the row
                sumForOneRow = sumForOneRow + integerValue;
            }
            // Now, the inner for loop for the 4 columns is done. Show sum to user
            std::cout << " --> " << sumForOneRow << '\n';

            // Line activities are done now for this line. Go on with next line
        }

    }
    else std::cerr << "\n*** Error: Could not open 'col.csv'\n";
    return 0;
}

IMHO this is more complicated than 3rd try恕我直言,这比第三次尝试更复杂

Yes, I can help you with a piece of code, but I am not sure, if you will understand the more modern C++ language elements.是的,我可以用一段代码帮助你,但我不确定你是否会理解更现代的 C++ 语言元素。

So, what do we need to do?那么,我们需要做什么呢?

  • Read line by line of the source csv string逐行读取源csv字符串
  • Get all integer values for this line获取此行的所有 integer 值
  • The interger values are arranged in columns and separated by white space整数值按列排列并用空格分隔
  • Show the values and the screen显示值和屏幕
  • Sum up the values in onbe line and show the sum总结 onbe 行中的值并显示总和

And in the resulting code, we will do exactly that.在生成的代码中,我们将这样做。

So, first, we open the file, and check, it it could be opened.因此,首先,我们打开文件,并检查它是否可以打开。 Then, in a simple for loop, we read all lines that are present in the source code.然后,在一个简单for循环中,我们读取源代码中存在的所有行。 Line by line.逐行。

In the body of the for loop, we take the current line that we just read, and put it into an std::istringstream .for循环的主体中,我们将刚刚读取的当前行放入std::istringstream中。 We do that to make extraction of the integer value simpler.我们这样做是为了更简单地提取 integer 值。 And for the extraction, we use the std::istream_iterator .对于提取,我们使用std::istream_iterator This will iterate over all integers in the line and return them.这将遍历该行中的所有整数并返回它们。

We will store the values temporary in a std::vector .我们将值临时存储在std::vector中。 We use the range constructor of the std::vector .我们使用std::vector的范围构造函数。 The begin iterator is the std::istream_iterator for the data type int and and for our std::istringstream .开始迭代器是数据类型int和我们的std::istringstream的 std:: std::istream_iterator The end iterator is the default constructed std::istream_iterator , so, simply {}.结束迭代器是默认构造的std::istream_iterator ,因此,只需 {}。 This will copy all values into the std::vector这会将所有值复制到std::vector

That is a powerful and compact on-liner.那是一个强大而紧凑的联机。

We copy the values in the std::vector , so, the integer values of one line to the console.我们复制std::vector中的值,因此,一行的 integer 值到控制台。

Then, we add up all values in the std::vector (all integers from one line) and show the result on the screen.然后,我们将std::vector中的所有值(一行中的所有整数)相加并在屏幕上显示结果。

And the beauty of it: It doesn't matter, how many rows and columns are present.它的美妙之处在于:存在多少行和列并不重要。 It will work always.它会一直工作。 The only thing we need is space separated integer values in lines.我们唯一需要的是行中以空格分隔的 integer 值。

And all this can be done with just 7 statements.而这一切只需 7 条语句即可完成。 . . . .

Please see:请参见:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric>

int main() {
    // Open file and check, if it could be opened
    if (std::ifstream csv{ "col.csv" }; csv) {

        // Read all lines from the source file
        for (std::string line{}; std::getline(csv, line); ) {

            // Put the current line in a stringstream for better extraction
            std::istringstream iss{ line };

            // Exctract all integer values from this line and put them int a vector
            std::vector values(std::istream_iterator<int>(iss), {});

            // Show values on display
            std::copy(values.begin(), values.end(), std::ostream_iterator<int>(std::cout, " "));

            // Claculate the sum for one line on show on display.
            std::cout << " --> " << std::accumulate(values.begin(), values.end(), 0) << '\n';
        }
    }
    else std::cerr << "\n*** Error: Could not open 'col.csv'\n";
    return 0;
}

Language is C++ 17语言为 C++ 17

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

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