C++ 动态扩展阵列以导入数据的好方法是什么?
我正在寻找有关创建动态扩展阵列以从.csv文件导入数据的帮助。我不想看到文件有多大,也不想在源代码中编辑变量/提示用户,我只想导入数据,然后以各种方式进行操作。首先,我的代码是: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
#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;c std::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;
}