我试图将一些我不认识的人用C编写的与研究相关的代码转换为C ++,而且绝对没有文档。 基本上将T *和T **对象转换为矢量和更加用户友好的容器。
Atm我有两个变量,
double* data
double* references
我在SO上看到了一个技巧,可以使正则向量易于分配给double *,如下所示:
references = &(*m_DataMaxPoints)[0];
没关系。
但是,应该从std::vector<std::vector<double>>* m_Data;
我不知道该如何分配。
我尝试过&(*m_Data)[0][0];
,但我真的不知道该怎么办。
任何提示都将受到欢迎..:(
编辑1:C程序中数据的原始处理*
double *数据在main()中声明
int main(int argc, char *argv[])
{
FILE *infile;
int verbose_flag = FALSE;
double *data = NULL, *reference = NULL, *maximum = NULL;
int *cumsizes = NULL;
int nobj = 0, nruns = 0;
int k;
double volume = 0;
double time_elapsed;
read_input(stdin, "stdin", &data, &nobj, &cumsizes, &nruns);
read_input将文本文件中的数字解析为数组。
#define PAGE_SIZE 4096 // allocate one page at a time
#define DATA_INC (PAGE_SIZE/sizeof(double))
#define SET_INC 128 // assume 128 datasets (can grow)
int read_input(FILE *infile, const char *filename, double **datap, int *ncolsp, int **cumsizesp, int *nrunsp)
{
char b[2];
double number;
int newline; // last input was newline
int datai; // the current element of (*datap)
int col; // the column being read
int set = *nrunsp; // the current data set
int ncols = *ncolsp; // the number of columns
int datasize;
int setsize;
datai = (set == 0)
? 0
: ncols * (*cumsizesp)[set-1];
setsize = (set == 0)
? 0
: ((set-1) / SET_INC + 1) * SET_INC;
*cumsizesp = realloc(*cumsizesp, setsize * sizeof(int));
datasize = (datai == 0)
? 0
: ((datai - 1) / DATA_INC + 1) * DATA_INC;
*datap = realloc(*datap, datasize * sizeof(double));
// remove leading whitespace
fscanf (infile, "%*[ \t\n]");
if (feof(infile)) {
warnprintf("%s: file is empty.", filename);
return -1;
}
do {
newline = 0;
if (set == setsize) {
setsize += SET_INC;
*cumsizesp = realloc(*cumsizesp, setsize * sizeof(int));
}
(*cumsizesp)[set] = (set == 0) ? 0 : (*cumsizesp)[set-1]; // beginning of data set
while (newline == 0) {
col = 0; // beginning of row
while (newline == 0) {
if (fscanf(infile, "%lf", &number) != 1) {
char buffer[64];
fscanf(infile, "%60s", buffer);
errprintf(
"could not convert string `%s' to double, exiting...",
buffer);
}
if (datai == datasize) {
datasize += DATA_INC;
*datap = realloc(*datap, datasize * sizeof(double));
}
(*datap)[datai++] = number;
#if DEBUG > 2
fprintf(stderr, "set %d, row %d, column %d, x = %g\n",
set, (*cumsizesp)[set], col, number);
#endif
col++; // new column
fscanf(infile, "%*[ \t]");
newline = fscanf(infile, "%1[\n]", b);
}
if (!ncols)
ncols = col;
else if (col != ncols) {
if ((*cumsizesp)[0] == 0)
errprintf ("reference point has dimension %d"
" while input has dimension %d",
ncols, col);
else
errprintf("row %d has different length (%d)"
" than previous rows (%d), exiting...",
(*cumsizesp)[set], col, ncols);
}
(*cumsizesp)[set]++;
fscanf (infile, "%*[ \t]");
newline = fscanf (infile, "%1[\n]", b);
}
#if DEBUG > 1
fprintf (stderr, "Set %d, %d rows in total\n", set, (*cumsizesp)[set]);
#endif
set++; // new data set
fscanf (infile, "%*[ \t\n]");
} while (!feof(infile));
*ncolsp = ncols;
*nrunsp = set;
return 0;
}
我想做的是通过为此接口创建包装器类,将尽可能少的转换为C ++,以使其更易于使用并将其实现为更大的项目。
因此,文件解析和数据分配是通过向量完成的(它们不需要成为指针)。
解析之后,我希望将向量转换为C样式的数组,这样我就可以调用原始代码的函数,而不必添加向量来支持所有这些,因为我不知道如何读取它在纯C语言中实现(多目标进化算法的实现)。
原始代码最终会调用:
volume = hv(data, nobj, cumsizes[nruns-1], reference);
我想这样做:
double* data = &(*m_Data)[0][0]; // my 2d vector<double>
double* references = &(*m_DataMaxPoints)[0]; // 1d vector<double>
int cumsizes = m_Data->at(0).size();
m_Volume = hv(data, Objectives(), cumsizes, references);
答案 0 :(得分:2)
在向量上使用指针不是必需的必不可少的方法,如您的问题迭代器的评论中所述,但这将是一个不错的选择。无论如何,如果您真的想使用指针,请按以下步骤操作:
vector< vector<double> >* vec = new vector< vector<double> >(16);
for (size_t i = 0; i < 16; ++i) {
(*vec)[i].resize(16);
}
(*vec)[4][2] = 6.66;
这段代码创建了一个指针(vec),该指针指向未初始化的double型向量(尺寸为16x16),向量在位置[4] [2]处的值为6.66,我认为您现在就获得了合奏。
答案 1 :(得分:0)
std::vector
用于处理所有内存分配。它不需要malloc
,realloc
或new
。如果不重写很多代码,就无法有效地实现这一点。
如果您希望C代码在C ++中进行编译,则需要进行一些细微的更改,例如强制转换:
*datap = (double*)realloc(*datap, datasize * sizeof(double));
此外,您可以通过引用传递C ++对象,因此不需要指针。通过参考传递矢量。
最简单的方法来保留现有的C代码,然后将数据从datap
复制到vec
。示例:
void foo(std::vector<std::vector<double>> &vec)
{
//copy from datap to vec:
//add a new row:
vec.push_back(std::vector<double>{});
//add coloumns
vec.back().push_back(11.0f);
vec.back().push_back(12.0f);
vec.back().push_back(13.0f);
//add another row:
vec.push_back(std::vector<double>{});
//add coloumns
vec.back().push_back(21.0f);
vec.back().push_back(22.0f);
vec.back().push_back(23.0f);
}
int main()
{
std::vector<std::vector<double>> vec;
foo(vec);
for(size_t row = 0; row < vec.size(); row++)
{
for(size_t col = 0; col < vec[row].size(); col++)
printf("%3.0f, ", vec[row][col]);
printf("\n");
}
return 0;
}
或者您也可以用C ++重写整个代码。示例:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
void read_matrix(std::vector<std::vector<double>> &vec)
{
std::ifstream fin("file.txt");
if(!fin)
return;
std::string line;
while(std::getline(fin, line))
{
//add a new row:
vec.push_back(std::vector<double>{});
//add columns
std::stringstream ss(line);
double value;
while(ss >> value)
vec.back().push_back(value);
}
}
int main()
{
std::vector<std::vector<double>> vec;
read_matrix(vec);
...
return 0;
}