Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 动态扩展阵列以导入数据的好方法是什么?_C++_Arrays_Vector_Heap_Deque - Fatal编程技术网

C++ 动态扩展阵列以导入数据的好方法是什么?

C++ 动态扩展阵列以导入数据的好方法是什么?,c++,arrays,vector,heap,deque,C++,Arrays,Vector,Heap,Deque,我正在寻找有关创建动态扩展阵列以从.csv文件导入数据的帮助。我不想看到文件有多大,也不想在源代码中编辑变量/提示用户,我只想导入数据,然后以各种方式进行操作。首先,我的代码是: #include <fstream> #include <sstream> #include <iostream> int main() { //declare variables and arrays long rows = 170260; int cols = 5; doub

我正在寻找有关创建动态扩展阵列以从.csv文件导入数据的帮助。我不想看到文件有多大,也不想在源代码中编辑变量/提示用户,我只想导入数据,然后以各种方式进行操作。首先,我的代码是:

#include <fstream>
#include <sstream>
#include <iostream>

int main()
{

//declare variables and arrays
long rows = 170260;
int cols = 5;
double **rawData = new double*[rows]; //on heap because of size
for(long pi = 0; pi < rows; ++pi) //create an array of pointers
{
         rawData[pi] = new double[cols];
}
char buff[200];
double deltaT;
double carDeltaV;
double *carV = new double[rows]; //on heap because of size

//import raw data
std::cout << "Importing filedata.csv...";

std::ifstream rawInput("filedata.csv");

for(long r = 0; r < rows; ++r)
{
      rawInput.getline(buff, 200);
      std::stringstream ss(buff);

      for(int c = 0; c < cols; ++c) 
      {
            ss.getline(buff, 40, ',');
            rawData[r][c] = atof(buff);
      }
}

std::cout << "Done." << std::endl;

//create speed matrix
carV[0] = 0;

std::cout << std::endl << "Creating speed matrix...";

for (long i = 1; i < rows; ++i) 
{

    deltaT = rawData[i][0] - rawData[i-1][0];
    carDeltaV = rawData[i-1][3] * deltaT;
    carV[i] = carDeltaV + carV[i-1];
}

std::cout << "Done." << std::endl;

//write data to csv file
std::cout << std::endl << "Writing data to file...";

std::ofstream outputData;
outputData.open("outputdata.csv");

for(long r = 0; r < rows; ++r)
{
         outputData << rawData[r][0] << "," << rawData[r][3]/.00981 << ",";
         outputData << carV[r] << std::endl;
}

outputData.close();
std::cout << "Done." << std::endl;

//delete pointers
std::cout << std::endl << "Clearing memory...";

for(long pj = 0; pj < rows; ++pj)
{
         delete [] rawData[pj];
}
delete [] rawData;
delete [] carV;

std::cout << "Done." << std::endl;

std::cin.get();
return 0;

}
还有更多,但这应该足以理解我试图实现的目标。我已经读了一点向量,但是向量向量的概念对我来说有点混乱,我试图实现它,但没有成功。另外,我读到一个德克可能是我要找的?我没有这些方面的经验,而且在我看来,对我的应用程序来说,这可能有点过头了,因为我只是在一个方向上向一个数据数组追加数据

<免责声明:我在C++方面是新手,所以如果有任何你认为超过我的技能水平的概念,请让我知道,这样我就可以阅读它。 有什么建议吗

编辑:根据请求,这就是我如何尝试使用向量进行编辑的方法

std::vector<double> rawDataRow;
std::vector< std::vector<double> > rawDataMatrix;

//import raw data loop
std::ifstream rawInput("test.csv");

for(int i = 1; i > 0; ) {
          rawInput.getline(buff, 200);
          std::stringstream ss(buff);

          for(int c = 0; c < cols; ++c) {
                  ss.getline(buff, 40, ',');
                  value = atof(buff);
                  rawDataRow.push_back(value);

                  std::cout << rawDataRow[0] << std::endl;
          }
          timeDiff = timeAfter - timeBefore;
          timeBefore = timeAfter;
          timeAfter = rawDataRow[0];

          rawDataMatrix.push_back(rawDataRow);
}
std::vector rawDataRow;
std::vectorrawDataMatrix;
//导入原始数据循环
std::ifstream rawInput(“test.csv”);
对于(int i=1;i>0;){
获取行(buff,200);
标准::stringstream ss(浅黄色);
对于(int c=0;cstd::cout总结讨论中出现的问题:

你不能有一个数组向量,请看:你可以有一个指向数组的指针向量。但是,在这一点上,我不会把所有的内存处理都搞乱

最好的方法是使用向量保存代码,除了应该将
rawDataRow
的定义放在循环中,以便在每次迭代中清除其内容

std::vector< std::vector<double> > rawDataMatrix;

//import raw data loop
std::ifstream rawInput("test.csv");

for(int i = 1; i > 0; ) {
      std::vector<double> rawDataRow;
      rawInput.getline(buff, 200);
      std::stringstream ss(buff);

      // do the rest
}
std::vectorrawDataMatrix;
//导入原始数据循环
std::ifstream rawInput(“test.csv”);
对于(int i=1;i>0;){
std::向量rawDataRow;
获取行(buff,200);
标准::stringstream ss(浅黄色);
//做剩下的
}

似乎你让生活变得太艰难了。然而,关键的认识是,在以某种形式使用输入之前,你总是需要检查输入。一旦你这样做了,事情就很容易解决了

为了方便地处理行的输入,我要定义的第一件事是这个简单的操纵器,它将忽略逗号:

std::istream& comma(std::istream& in) {
    if ((in >> std::ws).peek() == ',') {
        in.ignore(); // the happy case: just skip over the comma
    }
    else if (!in.peek() == std::char_traits<char>::eof()) {
        in.setstate(std::ios_base::failbit); // unhappy: not the end and not a comma
    }
    return in;
}
std::istream和逗号(std::istream和in){
如果((在>>std::ws.peek()==',')){
in.ignore();//好的例子是:跳过逗号
}
如果(!in.peek()==std::char\u traits::eof()){
in.setstate(std::ios_base::failbit);//不高兴:不是结尾,也不是逗号
}
返回;
}
有了这一点,读取行并将其拆分为单元格就相当容易了:

std::vector<std::vector<double>> result;
for (std::string line; std::getline(in, line); ) {
    std::istringstream lin(line);
    std::vector<double> row;
    for (double d; d >> lin >> comma; ) {
        row.push_back(d);
    }
    if (!lin.eof()) {
        in.setstate(std::ios_base::failbit);
    }
    std::result.push_back(row);
}
if (!in.eof()) {
    std::cout << "there was an input error\n";
}
else {
    // result contains the result of reading...
}
std::向量结果;
for(std::string line;std::getline(in,line);){
std::istringstream lin(线路);
std::向量行;
for(双d;d>>林>>逗号;){
排。向后推(d);
}
如果(!lin.eof()){
in.setstate(std::ios_base::failbit);
}
标准::结果。推回(行);
}
如果(!in.eof()){

std::cout首先,您应该将程序分为三部分:

  • 从输入文件读取数据
  • 处理数据
  • 将数据写入输出文件
  • 您的主程序基本上应如下所示:

    int main() {
      vector<InputRecord> data = read_from_csv("filedata.csv");
      vector<double> speeds = compute_speeds(data);
      write_to_csv("result.csv", data, speeds);
      return 0;
    }
    
    struct InputRecord {
      double timestamp;
      double field2;
      double field3;
      double location;
      double field5;
    };
    
    使用此数据结构,您可以编写
    数据[0]。时间戳
    而不是
    数据[0][0]
    ,这意味着您不再需要注释

    这是我为这项任务编写的完整代码。它做的事情与您的类似,应该是一个很好的起点。请注意,这段代码根本不做显式内存管理

    #include <cstdio>
    #include <cstdlib>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>
    
    using std::string;
    using std::vector;
    
    struct InputRecord {
      double timestamp;
      double field2;
      double field3;
      double location;
      double field5;
    };
    
    vector<InputRecord> read_from_csv(const char *filename) {
      std::ifstream in(filename);
      vector<InputRecord> data;
    
      if (!in.is_open()) {
        throw std::ios_base::failure(string()
            + "cannot open input file \"" + filename + "\".");
      }
    
      string line;
      while (std::getline(in, line)) {
        InputRecord rec;
        char end_of_line;
        if (std::sscanf(line.c_str(), "%lf,%lf,%lf,%lf,%lf%c",
            &rec.timestamp, &rec.field2, &rec.field3,
            &rec.location, &rec.field5, &end_of_line) != 5) {
          throw std::ios_base::failure(string()
              + "input file \"" + filename + "\" "
              + "contains invalid data: \"" + line + "\"");
        }
        data.push_back(rec);
      }
      if (in.bad()) {
        throw std::ios_base::failure(string() + "error while reading data");
      }
      return data;
    }
    
    vector<double> calculate_speeds(const vector<InputRecord> &data) {
      vector<double> speeds;
    
      speeds.push_back(0.0);
      for (std::size_t i = 1; i < data.size(); i++) {
        double delta_t = data[i].timestamp - data[i - 1].timestamp;
        double delta_s = data[i].location - data[i - 1].location;
        speeds.push_back(delta_s / delta_t);
      }
      return speeds;
    }
    
    void write_to_csv(const char *filename, const vector<InputRecord> &data,
        const vector<double> &speeds) {
      std::ofstream out(filename);
    
      if (!out.is_open()) {
        throw std::ios_base::failure(string()
            + "cannot open output file \"" + filename + "\".");
      }
      for (std::size_t i = 0; i < data.size(); i++) {
        out << data[i].timestamp << "," << speeds[i] << "\n";
      }
      if (out.bad()) {
        throw std::ios_base::failure(string() + "error while writing data");
      }
    }
    
    int main() {
      vector<InputRecord> data = read_from_csv("in.csv");
      vector<double> speeds = calculate_speeds(data);
      write_to_csv("out.csv", data, speeds);
      return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    使用std::string;
    使用std::vector;
    结构输入记录{
    双时间戳;
    双字段2;
    双字段3;
    双重定位;
    双字段5;
    };
    从csv读取向量(常量字符*文件名){
    std::ifstream-in(文件名);
    矢量数据;
    如果(!in.is_open()){
    抛出std::ios_base::failure(字符串()
    +“无法打开输入文件\”“+文件名+”\”;
    }
    弦线;
    while(std::getline(in,line)){
    InputRecord rec;
    _行的char end_;
    如果(std::sscanf(line.c_str(),%lf,%lf,%lf,%lf,%lf%c),
    &记录时间戳、记录字段2和记录字段3,
    &记录位置和记录字段5和记录行末尾)!=5){
    抛出std::ios_base::failure(字符串()
    +“输入文件\”+文件名+“\”
    +“包含无效数据:\”“+行+\”);
    }
    数据。推回(rec);
    }
    if(in.bad()){
    抛出std::ios_base::failure(字符串()+“读取数据时出错”);
    }
    返回数据;
    }
    矢量计算速度(常数矢量和数据){
    矢量速度;
    速度。推回(0.0);
    对于(std::size_t i=1;i使用带有合适类型的
    T
    std::vector
    固定元件并使用
    vector。向后推(值)
    追加每条记录。该类将根据需要处理增长。你能用向量显示你的代码吗?你只使用第一列和第四列吗?如果是这样,你可以通过不将字符串转换为每行其他三个值的两倍来节省工作量。@DietmarKühl这就是我试图实现的,
    #include <cstdio>
    #include <cstdlib>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>
    
    using std::string;
    using std::vector;
    
    struct InputRecord {
      double timestamp;
      double field2;
      double field3;
      double location;
      double field5;
    };
    
    vector<InputRecord> read_from_csv(const char *filename) {
      std::ifstream in(filename);
      vector<InputRecord> data;
    
      if (!in.is_open()) {
        throw std::ios_base::failure(string()
            + "cannot open input file \"" + filename + "\".");
      }
    
      string line;
      while (std::getline(in, line)) {
        InputRecord rec;
        char end_of_line;
        if (std::sscanf(line.c_str(), "%lf,%lf,%lf,%lf,%lf%c",
            &rec.timestamp, &rec.field2, &rec.field3,
            &rec.location, &rec.field5, &end_of_line) != 5) {
          throw std::ios_base::failure(string()
              + "input file \"" + filename + "\" "
              + "contains invalid data: \"" + line + "\"");
        }
        data.push_back(rec);
      }
      if (in.bad()) {
        throw std::ios_base::failure(string() + "error while reading data");
      }
      return data;
    }
    
    vector<double> calculate_speeds(const vector<InputRecord> &data) {
      vector<double> speeds;
    
      speeds.push_back(0.0);
      for (std::size_t i = 1; i < data.size(); i++) {
        double delta_t = data[i].timestamp - data[i - 1].timestamp;
        double delta_s = data[i].location - data[i - 1].location;
        speeds.push_back(delta_s / delta_t);
      }
      return speeds;
    }
    
    void write_to_csv(const char *filename, const vector<InputRecord> &data,
        const vector<double> &speeds) {
      std::ofstream out(filename);
    
      if (!out.is_open()) {
        throw std::ios_base::failure(string()
            + "cannot open output file \"" + filename + "\".");
      }
      for (std::size_t i = 0; i < data.size(); i++) {
        out << data[i].timestamp << "," << speeds[i] << "\n";
      }
      if (out.bad()) {
        throw std::ios_base::failure(string() + "error while writing data");
      }
    }
    
    int main() {
      vector<InputRecord> data = read_from_csv("in.csv");
      vector<double> speeds = calculate_speeds(data);
      write_to_csv("out.csv", data, speeds);
      return 0;
    }