编辑:解决了我的问题。由于我的CSVReader分隔符错误,这是一个愚蠢的错误……我的循环按照我的期望运行! 谢谢你的支持!
我试图在一系列for循环中声明临时变量。为此,我对每个“向量容器”(即vector<vector<string> > containerXYZ
)使用基于范围的循环,并在每个for循环中声明临时变量。
这是我的代码的一部分,可让您了解for循环:
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <iterator>
using namespace std;
//Global variables
string i {};
string j {};
class CSVReader
{
...
vector<vector<string> > getData1();
vector<vector<string> > getData2();
vector<vector<string> > getData3();
}
vector<vector<string> > CSVReader::getData1()
{...};
vector<vector<string> > CSVReader::getData2()
{...};
vector<vector<string> > CSVReader::getData3()
{...};
int main(int argc, char** argv)
{
vector<vector<string> > Container1 = reader.getData1; //reads data from file1
vector<vector<string> > Container2 = reader.getData2; //reads data from file2
//-----FIRST LOOP....
for(vector<string> vecOfContainer1 : Container1)
{
i = vecOfContainer1[0]; //Declaring temporary variables used for container3 in my vector-function
j = vecOfContainer1[1];
vector<vector<string> > Container3 = reader.getData3(); //reads data from file1
//-----SECOND LOOP....
for(vector<string> vecOfContainer2 : Container2)
{
string var1_str = vecOfContainer2[2]; //Temporary variables which probably cause the error...
string var2_str = vecOfContainer2[3];
float var1 = stof(var1_str);
float var2 = stof(var2_str);
//Do calculations...
};
};
return 0;
}
我现在的问题是代码构建正确,但是在运行时,它在完成循环并在输出中出现逻辑错误之前终止:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
RUN FAILED (exit value 3, total time: 3s)
经过一些研究,我认为“悬挂参考”是解决我的问题的关键词。但是,由于我的变量声明在第一个循环中效果很好,因此在第二个循环中效果不佳。我想在这里寻求帮助!?
让我知道您是否需要完整的代码。我认为这足以进行讨论...
答案 0 :(得分:0)
您无需事先检查所有临时变量的实际大小,但可以使用vecOfContainer1[0]
等进行访问而无需任何检查。
您应使用vecOfContainer1.at(0)
,它至少为您提供一个std::out_of_range
异常,该异常应为您提供更多详细信息。
答案 1 :(得分:0)
好的...由于我缺乏调试能力,因此我将向感兴趣的每个人发布完整的代码:
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <iterator>
using namespace std;
//Global variables
string line {};
string i {};
string j {};
/*
* CSV Reader class to open CSV file which is further parsed
* in vector containers
*/
class CSVReader
{
string fileName, delimiter;
public:
CSVReader(string filename, string delm = ";") :
fileName(filename), delimiter(delm)
{}
vector<vector<string> > getContainer1(); //Function to fetch unique objects from CSV file
vector<vector<string> > getContainer3(); //Fetch all corresponding lines to object_i,j
};
class CSVXReader
{
string fileName, delimiter;
public:
CSVXReader(string filename, string delm = ",") : //Notice comma delimiter for CSVX file, instead of semicolon for CSVReader
fileName(filename), delimiter(delm)
{}
vector<vector<string> > getContainer2(); //Fetch data from CSVX file
};
/*
* Boolean function template to search for a string in vector and return "true"
* Use it as: if(Contains(vector,item)){do...} :if vector contains "item", do...
*/
template <typename T>
const bool Contains( vector<T>& Vec, const T& Element)
{
if (std::find(Vec.begin(), Vec.end(), Element) != Vec.end())
return true;
return false;
};
/*
* Parse through CSV file line by line
* and return the data in vector of vector
* of strings
*/
vector<vector<string> > CSVReader::getContainer1()
{
ifstream file(fileName);
vector<vector<string> > Container1; //Vector of vector contains all unique objects_i,j with constants
while (getline(file, line)) //Iterate through each line and split the content using delimiter
{
vector<string> vecOfContainer1; //Vector contains a row from CSV file
boost::algorithm::split(vecOfContainer1, line, boost::is_any_of(delimiter)); //Vector content is delimited
i = vecOfContainer1.at(2); //Here: object No., e.g. 1_380
j = vecOfContainer1.at(3); //hotspot = 1,2,...,10 i.e. element j of object_i
int a = 0; //Integer variable, used in following if-loop to validate whether 'object' & 'hotspot'
//appear for the first time or not
/*
* Creating a vector containing only necessary constants of the
* corresponding line to copy into 'Container1'
*/
vector<string> constantsOfVec;
constantsOfVec = vecOfContainer1;
constantsOfVec.erase(constantsOfVec.begin()+11,constantsOfVec.begin()+21); //Deleting unnecessary elements of vecOfContainer1
constantsOfVec.erase(constantsOfVec.begin()+4,constantsOfVec.begin()+8);
/*
* Searching whether 'object' i & 'hotspot' j exists in the whole 'Container1' already.
* If it exists, a=>1, and at next if-function the current vector (i.e. line) is not added to 'Container1'
* else, a=>0, and current vector is added!
*/
for(vector<string> constantsOfVec : Container1) //Browsing through all vectors of 'Container1'
{
if(Contains(constantsOfVec, i) && Contains(constantsOfVec, j)) //Browsing through a vector (i.e. line) and searching for 'detail' i (e.g. 1_380) & hotspot j
{
a = 1;
}
}
if(a != 1) //Line (or vector) is added to 'Container1' container if i&j appear for the first time
{
Container1.push_back(constantsOfVec);
}
}
Container1.erase(Container1.begin()); //Deletes first line of CSV file, i.e. column header
file.close();
return Container1;
};
vector<vector<string> > CSVReader::getContainer3()
{
ifstream file(fileName);
vector<vector<string> > Container3; //Vector of vector contains all lines of object_i,j
while (getline(file, line)) //Iterate through each line and split the content using delimiter
{
vector<string> vecOfContainer1; //Vector contains a row from RAO file
boost::algorithm::split(vecOfContainer1, line, boost::is_any_of(delimiter)); //Vector content is delimited
/*
* Creating a vector containing only necessary elements of the
* corresponding line to copy into 'Container3' container
*/
vector<string> parameterOfVec;
parameterOfVec = vecOfContainer1;
parameterOfVec.erase(parameterOfVec.begin()+21,parameterOfVec.end());
parameterOfVec.erase(parameterOfVec.begin()+8,parameterOfVec.begin()+12);
parameterOfVec.erase(parameterOfVec.begin()+4,parameterOfVec.begin()+7);
parameterOfVec.erase(parameterOfVec.begin(),parameterOfVec.begin()+2);
if(Contains(parameterOfVec, i) && Contains(parameterOfVec, j)) //Browsing through a vector (i.e. line) and searching for detail i and hotspot j of corresponding loop
{
Container3.push_back(parameterOfVec);
};
};
file.close();
return Container3;
};
vector<vector<string> > CSVXReader::getContainer2()
{
ifstream file(fileName);
vector<vector<string> > Container2;
while (getline(file, line))
{
vector<string> vecOfContainer2;
boost::algorithm::split(vecOfContainer2, line, boost::is_any_of(delimiter));
Container2.push_back(vecOfContainer2);
};
Container2.erase(Container2.begin()); //Deletes first line of CSVX file, i.e. column header
file.close();
return Container2;
};
int main(int argc, char** argv)
{
CSVReader readerCSV("CSV_Example_.csv"); //Creating an object of CSVReader to open CSV file
CSVXReader readerCSVX("CSVX_Example.csvx"); //Creating an object of CSVXReader to open CSVX file
vector<vector<string> > Container1 = readerCSV.getContainer1(); //Read data from CSV file and insert all unique objects (i,j) in 'Container1'
vector<vector<string> > Container2 = readerCSVX.getContainer2();
////------------------------------FIRST LOOP FOR OBJECT i, HOTSPOT j---------------------------------------------------------------------////
for(vector<string> constantsOfVec : Container1) //Iterating through 'Container1'
{
i = constantsOfVec.at(2); //Declare Object No. and Hotspot of the current loop to be used
j = constantsOfVec.at(3); //in 'Container3' for inserting all vectors with exact same i&j in while-loop
vector<vector<string> > Container3 = readerCSV.getContainer3(); //Read data from CSV file and insert all lines with corresponding i&j in 'Container3' container
////------------------------------SECOND LOOP FOR TIME k---------------------------------------------------------------------------------////
for(vector<string> vecOfContainer2 : Container2) //Iterating through 'Container2', i.e. time k
{
string var1_str = vecOfContainer2.at(10);
string var2_str = vecOfContainer2.at(12);
string var3_str = vecOfContainer2.at(16);
//Converting strings of 'Container3' to floats with std::stof('string')
float var1 = stof(var1_str);
float var2 = stof(var2_str);
float var3 = stof(var3_str);
//get parameterOfVec(var1,var2,var3)_ij for time k, i.e. find line in Container3 with closest parameters to current line of Container2
};
};
return 0;
}
我嵌套了循环,因为我想在遍历容器1时创建自己的Container3,例如push_back
file1的所有行都属于object_i,j。
在第二个循环中,我正在浏览另一个file2,并且必须为Container2(file2)的每一行查找Container3(file1)中的相应行。必须对所有object_ij,即Container1(file1)的所有行重复此操作。
这就是为什么我一开始创建Container2以便为每个object_ij访问它的原因。根据我的理解,Container3是一个与每个object_ij对应的临时容器。
希望您能理解我的理解...期待任何建议。同时,我正在努力赶上调试器,并将尽快发布更多信息。
BR jtotheakob