我已经习惯了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数组,您需要将行和列的值传递给具有数组基地址的函数。
希望这对你有帮助!