在自定义库中操作2d C++数组-获取行数

Manipulating 2d C++ arrays in a custom library - getting the number of rows?

本文关键字:数组 获取 C++ 2d 自定义 操作      更新时间:2023-10-16

我已经习惯了Java,但正在学习C++,作为一个实验,我正在尝试创建一个库,将CSV文件读取到具有用户定义的导入规范的2d数组中,将数组打印到控制台,然后将数组写入一个单独的文件。

在创建数组、打印数组和写入数组时,我一直纠结于如何确定2d数组中要循环的行数(y轴(。我得到了x轴的值,我一直在摆弄这个:

int y = sizeof(arr) / sizeof(arr[0]);

尝试获取它。当我在一个编译的cpp main中测试所有代码时,它得到了正确的行数,但现在我已经将函数移动到一个包含的库中,它将0分配给y!

为什么会有差异,我该如何解决?在下面的例子中,我正在测试一个有6个字段和4条记录的矩阵,所以我期望4作为分配给y的值。

由于我已经将问题缩小到这个变量,这里(希望(是我如何获得y.的SSCCE

头文件:

#ifndef CSV_IO_H
#define CSV_IO_H
#include <string>
using namespace std;
class csv_io
{
    public:
        static void csv_to_dbl_arr(string, double arr[][6], char, char);
        static void print_dbl_arr(double arr[][6]);
};
#endif

包含的库:

#include "csv_io.h"
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
using namespace std;
void csv_io::csv_to_dbl_arr(string inf, double arr[][6], char dlm, char sep)
{
    ifstream ifs;
    string row, col, val;
    int i = 0;
    int j = 0;
    ifs.open(inf.c_str());
    if(ifs.is_open())
    {
        while(ifs.good())
        {
            getline(ifs, row, sep);
            stringstream col(row);
            while(col.good())
            {
                getline(col, val, dlm);
                arr[i][j] = atof(val.c_str());
                j++;
            }
            j = 0;
            i++;
        }
    }
    ifs.close();
}
void csv_io::print_dbl_arr(double arr[][6])
{
    int x = sizeof(arr[0]) / sizeof(double);
    int y = sizeof(arr) / sizeof(arr[0]);
    cout << "x: " << x << endl << "y: " << y << endl;
}

主.cpp

#include "csv_io.h"
#include "csv_io.cpp"
#include <stdlib.h>
using namespace std;
int main()
{
    double d_arr[4][6];
    string inf = "file_i.txt";
    char in_dlm = ',';
    char in_sep = 'n';
    csv_io::csv_to_dbl_arr(inf, d_arr, in_dlm, in_sep);
    csv_io::print_dbl_arr(d_arr);
    return 0;
}

file_i.txt:

1,1,1,1,1,1
2,2,2,2,2,2
3,3,3,3,3,3
4,4,4,4,4,4

我知道我可以做一个柜台&跟踪csv_to_dbl_arr中的行数,但我想弄清楚我为y使用的表达式,这样我就可以动态使用它,而不必在main中声明它。

void print_dbl_arr(double arr[][6])等价于
void print_dbl_arr(double (*arr)[6])

所以

  • sizeof(arr)是指针的大小
  • CCD_ 4是CCD_ 5的大小,所以CCD_

您可以使用模板和通过引用传递数组来获得如下大小:

template <std::size_t N, std::size_t M>
void print_dbl_arr(double (&arr)[N][M]);

使用std::vector/std::array更直观。

double d_arr[4][6];
void csv_io::print_dbl_arr(double arr[][6])
    {
        int x = sizeof(arr[0]) / sizeof(double);
        int y = sizeof(arr) / sizeof(arr[0]);
        cout << "x: " << x << endl << "y: " << y << endl;
    }
csv_io::print_dbl_arr(d_arr);

当您将数组d_arr传递给print_dbl_arr时,它会衰减为一个指针(double (*arr)[6](。所以sizeof(arr)在32位平台上是4。并且arr[0]是具有大小48(假定sizeof(double)是8(的六个二重的1D阵列。积分除法CCD_ 15的结果为零。

1D数组也会发生同样的情况(在这两种情况下,都是为最高维度指定的[](。这就是为什么我们需要将数组的元素数量作为另一个参数传递,以便被调用者能够知道它

int arr[4];
void f(int arr[], int n)
{
    // The wrong way
    // arr is decayed to a pointer, int *arr.
    // for (size_t i = 0; i < sizeof(arr); ++i)
    // {
    //    // iterate over the array
    // }
    // The correct way
    for (size_t i = 0; i < n; ++i)
    {
        // iterate over the array
    }
}

当您将整数/浮点/双数组传递给函数时,意味着您只传递数组的基地址(因为数组名称表示基地址(

在以下功能中:

void csv_io::print_dbl_arr(double arr[][6])
{
   int x = sizeof(arr[0]) / sizeof(double); // here you are dividing sizeof(address of array) with sizeof(double)
   // because arr and arr[0] both represents the base address of the array in 2D array
   int y = sizeof(arr) / sizeof(arr[0]); // Its indirectly means that dividing the size of base addresses
   cout << "x: " << x << endl << "y: " << y << endl;
}

为了避免这种类型错误,无论何时将1D数组传递给函数,都应该传递该数组中的元素总数。对于2D数组,您需要将行和列的值传递给具有数组基地址的函数。

希望这对你有帮助!