将 C 代码转换为 C++,将 double* 转换为向量,将 2D 向量转换为 double*

问题描述 投票:0回答:2

我正在尝试将一些我不认识的人用 C 语言编写的与研究相关的代码(绝对没有文档)转换为 C++。 基本上将 T* 和 T** 对象转换为向量和更用户友好的容器。

Atm 我有两个变量,

double* data
double* references

我在这里看到了一个技巧,它可以使正则向量轻松分配给 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);
    
c++ c
2个回答
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 ),指向未初始化的双精度向量向量(维度为 16x16),位置 [4][2] 处值为 6.66,我想您现在已经得到了合成。


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 columns 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 columns 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; }
    
© www.soinside.com 2019 - 2024. All rights reserved.