QRegExp a filename but its not matching - c++

I'm trying to parse date time from a PNG file but can't quite get it with QRegExp
this_png_20211208_1916.png
QDateTime Product::GetObstime()
{
QDateTime obstime;
QString filename = FLAGS_file_name.c_str();
QString year, month, day, hour, minute, second;
QRegExp regexp = QRegExp("^.*\\w+_(\\d{4}\\d{2}\\d{2})_(\\d{2}\\d{2})\\.png$");
VLOG(3) << " filename: " << filename.toStdString();
if(regexp.indexIn(filename) !=-1)
{
VLOG(3) << " filename: " << filename.toStdString();
QStringList dt_bits = regexp.capturedTexts();
if(dt_bits.size() >=2)
{
year = dt_bits.at(1).mid(0, 4);
month = dt_bits.at(1).mid(5, 2);
day = dt_bits.at(1).mid(8, 2);
hour = dt_bits.at(2).mid(0, 2);
minute = dt_bits.at(2).mid(3, 2);
second = dt_bits.at(2).mid(3, 2);
VLOG(3) << " Year: " << year.toStdString()
<< " Month: " << month.toStdString()
<< " Day: " << day.toStdString()
<< " Hour: " << hour.toStdString()
<< " Min: " << minute.toStdString()
<< " Sec: " << second.toStdString();
QString datetime_str = year + "-" + month + "-" + day +
"T" + hour + ":" + minute + second + "00Z";
obstime = QDateTime::fromString(datetime_str, Qt::ISODate);
if (obstime.isValid())
{
VLOG(3)<<"Date iS VALID: "<<obstime.toString(Qt::ISODate).toStdString();
}
else
{
LOG(ERROR)<<" Error! Date Time bits did not match format.";
}
}
}
return obstime;
}
been using tools like https://regex101.com/
but to no avail. am I missing something?

You have the following errors in your code:
month = dt_bits.at(1).mid(5, 2); should be month = dt_bits.at(1).mid(4, 2); because the index is 0-based, not 1-based
day = dt_bits.at(1).mid(8, 2); should be day = dt_bits.at(1).mid(6, 2);
minute = dt_bits.at(2).mid(3, 2); should be minute = dt_bits.at(2).mid(2, 2);
second = dt_bits.at(2).mid(3, 2); should be second = "00"; because your filenames do not contain seconds
Generally I would recommend doing all of the work in the regex instead of doing some fancy splitting using QString::mid():
QRegExp regexp = QRegExp("^.*\\w+_(\\d{4})(\\d{2})(\\d{2})_(\\d{2})(\\d{2})\\.png$");
This gives you all the fields in separate groupings, no need for QString::mid() at all.

Related

Month auto increment using mktime and timegm functions in C++

I'd like to convert a string date (UTC) to a timestamp using C++.
It works fine except for the month, which is auto incremented by one.
If the string is 20221222074648, for 2022-12-22 07:46:48, the timestamp will be 1674373608, which is the timestamp of 2023-01-22 07:46:48.
I don't understand the reason of this auto-increment, because there's no changes of the month's variable in the code below.
cout << "date : " << receivedDate << endl;
struct tm t;
time_t timestamp;
size_t year_size = 4;
size_t other_size = 2;
t.tm_year = stoi(receivedDate.substr(0, 4), &year_size, 10) - 1900;
t.tm_mon = stoi(receivedDate.substr(4, 2), &other_size, 10);
t.tm_mday = stoi(receivedDate.substr(6, 2), &other_size, 10);
t.tm_hour = stoi(receivedDate.substr(8, 2), &other_size, 10);
t.tm_min = stoi(receivedDate.substr(10, 2), &other_size, 10);
t.tm_sec = stoi(receivedDate.substr(12, 2), &other_size, 10);
t.tm_isdst = -1;
cout << "year : " << t.tm_year + 1900 << "\nmonth : " << t.tm_mon << "\nday : " << t.tm_mday << "\nhour : " << t.tm_hour << "\nminutes : " << t.tm_min << "\nseconds : " << t.tm_sec << endl;
timestamp = timegm(&t);
cout << "timestamp : " << timestamp << endl;
cout << "asctime timestamp : " << asctime(&t);
Your problem is pretty simple !
the tm.tm_mom goes from 0 to 11, You need to add -1 on your month value
t.tm_mon = stoi(receivedDate.substr(4, 2), &other_size, 10) - 1;

Name format Lab

CLICK HERE TO SEE THE IMAGE PROBLEM
C++ - I'm having a big problem with my code and I don't understand where I did the mistake because I'm not getting the result that I want for example the 1st output that problem is asking me :(
My FULL CODE
Outputs that I'm getting wrong
#include <iostream>
#include <string>
using namespace std;
int main() {
string firstName, middleName, lastName, theName;
getline(cin, theName);
int findN = theName.find(" ");
firstName = theName.substr(0, findN);
int findN2 = theName.find(" ", findN + 1);
if (findN2 != string::npos){
middleName = theName.substr(findN2 + 1, findN2 - findN - 1);
lastName = theName.substr(findN2 + 1, theName.length() - findN2 - 1);
cout << lastName << ", " << firstName[0] << "." << middleName[0] << "." << endl;
}
else {
lastName = theName.substr(findN + 1, theName.length() - findN - 1);
cout << lastName << ", " << firstName[0] << " . " << endl;
}
return 0;
}
I suggest learning to use debugger.
#include <iostream>
#include <string>
using namespace std;
int main() {
string firstName, middleName, lastName, theName;
getline(cin, theName);
int findN = theName.find(" ");
firstName = theName.substr(0, findN);
int findN2 = theName.find(" ", findN + 1);
if (findN2 != string::npos) {
//changed from findN2 + 1 to findN + 1
middleName = theName.substr(findN + 1, findN2 - findN - 1);
lastName = theName.substr(findN2 + 1, theName.length() - findN2 - 1);
cout << lastName << ", " << firstName[0] << "." << middleName[0] << "." << endl;
}
else {
lastName = theName.substr(findN + 1, theName.length() - findN - 1);
//fixed the white space " . " -> ". "
cout << lastName << ", " << firstName[0] << ". " << endl;
}
return 0;
}
This is easily solved with debugger.
If there is a second space, both of your middleName and middleName are assigned substring starting from findN2 + 1.
If there is no second space, you have extra spaces around . here: " . "

How to automatically generate new CSV file according to current time using C++

I have finished the task of reading sensor data and store into CSV file successfully. But everytime I want to stop reading & storing sensor data, I must close the exe file. Due to the factory operation, they want to continuously run the program during a month without closing the exe file. I was required to modify the code to generate a new CSV file after a period (e.g. 1 hour). So the file name maybe: 20190516_10h0m0s, 20190516_11h0m0s, 20190516_12h0m0s...
I tried to use (struct tm) and for(;timeinfo->tm_min < 60;) to make a new CSV produced after 60'. But every loop, the item Data, time, Channel are written to the CSV again. It looks weird. But when I create the file dest and put the dest.open outside for loop, it only store correct data format without creating a new CSV as I want. Please suggest me how to make it work as expectation.
void EX_GetMultiValue(LONG i_lDriverHandle,
WORD i_wSlotID,
struct SlotInfo &i_SlotInfo)
{
char filename[20], filename2[20];
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
timeinfo->tm_mon++; // Because the range of tm_mon is 0~11, so we need to increment it by 1
timeinfo->tm_year = timeinfo->tm_year + 1900; // Because year counted since 1900
clock_t start = clock();
sprintf(filename,
"%04d%02d%02d_%02dh%02dm%02ds.csv",
timeinfo->tm_year,
timeinfo->tm_mon,
timeinfo->tm_mday,
timeinfo->tm_hour,
timeinfo->tm_min,
timeinfo->tm_sec);
printf("\nFilename: %s", filename);
ofstream dest2;
dest2.open(filename, ios_base::app | ios_base::out);
dest2 << "Date" << "," << "Time" << "," << "milisecond" << ","
<< "Channel 0" << "," << "Channel 1" << "," << "Channel 2" << ","
<< "Channel 3" << "," << "Channel 4" << "," << "Channel 5" << ","
<< "Channel 6" << "," << "Channel 7" << "," << "Channel 8" << ","
<< "Channel 9" << "," << "Channel 10" << "," << "Channel 11" << ","
<< endl;
for (; timeinfo->tm_min < 60;)
{
ofstream dest;
dest.open(filename, ios_base::app | ios_base::out);
LONG lGetMultiValueResult = AIO_GetValues(i_lDriverHandle,
i_wSlotID,
wRawValue); //get raw value
if (ERR_SUCCESS == lGetMultiValueResult)
{
clock_t timeElapsed = clock() - start;
unsigned secElapsed = timeElapsed / CLOCKS_PER_SEC;
unsigned msElapsed = timeElapsed / CLOCKS_PER_MS;
while (msElapsed >= 1000)
msElapsed -= 1000;
while ((timeinfo->tm_sec + secElapsed) > 59)
{
timeinfo->tm_sec -= 60;
timeinfo->tm_min++;
}
while (timeinfo->tm_min > 59)
{
timeinfo->tm_min -= 60;
timeinfo->tm_hour++;
}
while (timeinfo->tm_hour > 23)
{
timeinfo->tm_hour -= 24;
timeinfo->tm_mday++;
}
dest << timeinfo->tm_year << "-" << timeinfo->tm_mon << "-"
<< timeinfo->tm_mday << "," << timeinfo->tm_hour << "h"
<< timeinfo->tm_min << "m" << timeinfo->tm_sec + secElapsed
<< "s" << ",";
dest << msElapsed << "ms" << ",";
for (iCnt = 0; iCnt < g_ChannelNum; iCnt++)
{
wRangeType = *(i_SlotInfo.wChRange + iCnt); //get range type
EX_ScaleRawValue(wRangeType,
wRawValue[iCnt],
&dScaledValue,
cUnit); //get scale value
if (strcmp(cUnit, "UN") != 0)
{
printf("Channel %d raw data is 0x%04X, scaled value is %.4f %s.\n",
iCnt,
wRawValue[iCnt],
dScaledValue,
cUnit);
dest << dScaledValue << ",";
Sleep(1);
}
else
printf("Channel %d range is unknown.\n", iCnt);
}
dest << endl;
}
else
printf("Fail to get value, error code = %d\n",
lGetMultiValueResult);
dest.close();
dest2.close();
if (dest == NULL)
{
perror("Error creating file: ");
return;
}
}
Using standard C++-facilities and Howard Hinnants date.h:
#include <chrono>
#include <string>
#include <iostream>
#include "date.h"
int main()
{
auto now{ std::chrono::system_clock::now() };
std::string filename{ date::format("%Y%m%e_%Hh%Mm%Ss.csv", now) };
std::cout << filename << '\n';
}
I don't know what you're trying to do with the rest of your code, so ...

C++ How do I create a timestamped directory using a filepath held in a string?

I am trying to set up a program which can create a new directory every time it is used to fill with data. I want the name of the folder to be a timestamp of when it was created. I have already written a function which creates the timestamp and returns it as a string.
string timestamp() {
//create a timecode specific folder
// current date/time based on current system
time_t now = time(0);
struct tm timeinfo;
localtime_s(&timeinfo, &now);
// print various components of tm structure.
cout << "Year: " << 1900 + timeinfo.tm_year << endl;
int Y = 1900 + timeinfo.tm_year;
cout << "Month: " << 1 + timeinfo.tm_mon << endl;
int M = 1 + timeinfo.tm_mon;
cout << "Day: " << timeinfo.tm_mday << endl;
int D = timeinfo.tm_mday;
cout << "Time: " << 1 + timeinfo.tm_hour << ":";
int H = timeinfo.tm_hour;
cout << 1 + timeinfo.tm_min << ":";
int Mi = timeinfo.tm_min;
cout << 1 + timeinfo.tm_sec << endl;
int S = 1 + timeinfo.tm_sec;
string timestampStr;
stringstream convD, convM, convY, convH, convMi, convS;
convD << D;
convM << M;
convY << Y;
convH << H;
convMi << Mi;
convS << S;
cout << "Timestamp:" << endl;
timestampStr = convD.str() + '.' + convM.str() + '.' + convY.str() + '-' + convH.str() + ':' + convMi.str() + ':' + convS.str();
cout << timestampStr << endl;
return timestampStr;
}
This bit works fine and gives me a string with the current timestamp. I also have a second string with the path to the folders location which I combine to give the full path and new folder name in a string eg "C:\\Users\\Daniel\\Documents\\VS17\\25.5.2017-16:47:51"
I know I can use
CreateDirectory(direc, NULL);
to make a directory when I have a file path like the one held in my string but in LPCWSTR format. So really my question is
How do I convert my string into a LPCWSTR format to use in CreateDirectory
Is there some other way I am just missing
Since your folder path string is a char based string, just use CreateDirectoryA() directly, instead of using the TCHAR based CreateDirectory() (which clearly is being mapped to CreateDirectoryW() in your project), eg:
string direc = "C:\\Users\\Daniel\\Documents\\VS17\\" + timestamp();
CreateDirectoryA(direc.c_str(), NULL);

Segmentation fault using unordered_map unordered_set on recursive function

I'm relatively new programming c++. I'm implementing a tree like index for a db using unorderd_map on the implementation of the tree data structure to store the children nodes. As im working with tree like structures the construction an search methods are recursive, also i store the pointers of the nodes, so i suspect i may have a sort of not well handled memory issue. I'm getting a segmentation fault. Next is my code and the output of it.
#include <memory>
#include <sstream>
#include <unordered_map>
#include <iostream>
#include <string>
#include <sqlite3.h>
#include "aux_functions.cpp"
#include <math.h>
using namespace std;
class TreeLikeIndex
{
public:
TreeLikeIndex(string attribute, string indices, int indices_count, short int is_leaf, unordered_map<string, TreeLikeIndex*> children);
TreeLikeIndex(string indices, int indices_count);
TreeLikeIndex();
string search(unordered_map<string, string> *);
private:
string indices;
int indices_count;
short int is_leaf;
string attribute;
unordered_map<string, TreeLikeIndex*> children;
};
string TreeLikeIndex::search(unordered_map<string, string> * _tuple)
{
if((*_tuple).empty() || this->is_leaf ) return this->indices;
string att_val = (*_tuple)[this->attribute];
(*_tuple).erase(this->attribute);
TreeLikeIndex * child_with_that_value = this->children[att_val];
return (*child_with_that_value).search(_tuple);
}
class DecisionTreeLikeIndexer
{
public:
DecisionTreeLikeIndexer(string, string, string);
int rebuild_index();
TreeLikeIndex * get_index();
private:
TreeLikeIndex * build_index(unordered_set<string> attributes_list, int depth, string comma_separated_ids, int ids_list_count);
TreeLikeIndex * index;
string source_db_address;
string dest_folder_address;
time_t time_of_last_build;
unordered_set<string> columns_names;
string source_table_name;
unordered_set<string> temp_tables_names;
string id_column_name;
sqlite3 * source_db_connection;
int table_count;
};
int DecisionTreeLikeIndexer::rebuild_index()
{
this->index = this->build_index(this->columns_names, 0, "", 0);
this->time_of_last_build = time(NULL);
return 0;
}
TreeLikeIndex * DecisionTreeLikeIndexer::get_index()
{
return this->index;
}
DecisionTreeLikeIndexer::DecisionTreeLikeIndexer(string source_db_address, string table_name, string dest_folder_address)
{
this->source_db_address = source_db_address;
this->dest_folder_address = dest_folder_address;
this->columns_names = Aux::get_column_names(source_db_address, table_name);
this->source_table_name = table_name;
this->id_column_name = "rowid";
this->source_db_connection = Aux::get_db_connection(this->source_db_address);
// Getting count of this table
sqlite3_stmt* statement;
string query = "SELECT count(*) FROM " + this->source_table_name + ";";
if(sqlite3_prepare(this->source_db_connection, query.c_str(), -1, &statement, 0) == SQLITE_OK)
{
int res = sqlite3_step(statement);
const unsigned char * count_char = sqlite3_column_text(statement,0);
if(res == SQLITE_ROW)
{
stringstream _temp;
_temp << count_char;
_temp >> this->table_count;
}
sqlite3_finalize(statement);
}
else
{
cout << "Error initializating Indexer (Getting initial table count): " << sqlite3_errmsg(this->source_db_connection) << endl;
}
}
TreeLikeIndex * DecisionTreeLikeIndexer::build_index(unordered_set<string> attributes_list, int depth, string comma_separated_ids, int ids_list_count)
{
if( attributes_list.size() <=1 || (depth > 0 && ids_list_count <= 1))
{
Aux::tabs(depth);
cout << "Leaf at depth: " << depth << " Ids are: " << comma_separated_ids << " Ids count: " << ids_list_count << endl;
static TreeLikeIndex * node = new TreeLikeIndex((string)comma_separated_ids, (int)ids_list_count);
return node;
}
string source_table = this->source_table_name;
int count = this->table_count;
if(depth > 0)
{
while(1)
{
source_table = *Aux::get_random_list_of_strings(1).begin();
if(this->temp_tables_names.insert(source_table).second) break;
}
const string create_temp_table_stmnt = "CREATE TEMP TABLE " + source_table + " AS SELECT * FROM " + this->source_table_name + " WHERE " + this->id_column_name + " IN(" + comma_separated_ids + ")";
sqlite3_exec(this->source_db_connection, create_temp_table_stmnt.c_str(),Aux::sqlt_callback,0,NULL);
count = ids_list_count;
Aux::tabs(depth);
cout << "Not root node" << endl;
}
Aux::tabs(depth);
cout << "Source table is: " << source_table << " Table count is: " << count << endl;
Aux::tabs(depth);
cout << "Attributes list is: "; for_each(attributes_list.begin(), attributes_list.end(),[](string v){cout << v << " ";});
cout << endl;
const double E = log2(count) ;
Aux::tabs(depth);
cout << "Entropy of node: " << E << endl;
string best_attribute;
double best_gain;
unordered_set<string> best_attribute_values;
for(string attr: attributes_list)
{
Aux::tabs(depth+1);
cout << "Analysing attribute: " << attr << endl;
const string get_at_count_values_query = "SELECT " + attr + ", count(" + attr + ") FROM " + source_table + " GROUP BY " + attr + ";";
sqlite3_stmt * stmnt;
double weighted_entropy = 0;
unordered_set<string> this_att_values;
if(sqlite3_prepare(this->source_db_connection, get_at_count_values_query.c_str(), -1, &stmnt, 0) == SQLITE_OK)
{
for(;;)
{
int res = sqlite3_step(stmnt);
if(res == SQLITE_DONE || res==SQLITE_ERROR)
{
double gAti = E - weighted_entropy;
Aux::tabs(depth+1);
cout << "Finish computing WE for att: " << attr << " Gain is: " << gAti << endl;
if(gAti > best_gain)
{
Aux::tabs(depth+1);
cout << "Found attribute with better gain." << endl;
best_gain = gAti;
best_attribute = attr;
best_attribute_values.clear();
Aux::tabs(depth+1);
for(string v:this_att_values)
{
best_attribute_values.insert(v);
}
cout << endl;
this_att_values.clear();
}
sqlite3_finalize(stmnt);
//delete &res;
break;
}
if(res == SQLITE_ROW)
{
string val = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmnt,0)));
int vSize = sqlite3_column_int(stmnt,1);
Aux::tabs(depth+2);
this_att_values.insert(val);
double ratio = double(vSize) / double(count);
weighted_entropy += double(ratio) * double(log2(vSize));
Aux::tabs(depth+2);
cout << "Processing value: " << val << " With vSize: " << vSize << " Current WE is: " << weighted_entropy << endl;
}
}
}
}
Aux::tabs(depth);
cout << "Finish processing attributes list. Best attribute is: " << best_attribute << " Best gain is: " << best_gain << endl;
Aux::tabs(depth);
cout << "Best attribute values are: "; for_each(best_attribute_values.begin(), best_attribute_values.end(), [](string v){cout << v << ",";}); cout << endl;
unordered_map<string, TreeLikeIndex *> children;
for(string val: best_attribute_values)
{
const string get_ids_of_bestatt_val = "SELECT rowid FROM " + source_table + " WHERE " + best_attribute + " = " + val + ";";
int ids_count = 0;
sqlite3_stmt * stmnt;
string ids = "";
bool first = 1;
int next_depth = depth + 1;
unordered_set<string> next_attributes_set;
for(string attr: attributes_list) if(attr != best_attribute) next_attributes_set.insert(attr);
if(sqlite3_prepare(this->source_db_connection, get_ids_of_bestatt_val.c_str(), -1, &stmnt,0) == SQLITE_OK)
{
for(;;)
{
int res = sqlite3_step(stmnt);
if(res == SQLITE_ROW)
{
string id = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmnt,0)));
if(!first) ids += "," + id;
else ids += id;
ids_count++;
}
if(res == SQLITE_DONE || res == SQLITE_ERROR)
{
Aux::tabs(depth+1);
cout << "Adding branch for val: " << val << endl;
Aux::tabs(depth+1);
cout << " Next attributes are: "; for_each(next_attributes_set.begin(), next_attributes_set.end(), [](string v){cout << v << ",";});
cout << " Depth is: " << next_depth << " Ids are: " << ids << " Ids count: " << ids_count << endl;
sqlite3_finalize(stmnt);
static TreeLikeIndex * temp_child = this->build_index(next_attributes_set, next_depth, ids, ids_count);
pair<string, TreeLikeIndex*> child (val, temp_child);
children.insert(child);
}
}
}
}
Aux::tabs(depth);
cout << "Finish processing node, will return." << endl;
static TreeLikeIndex * no_leaf_node = new TreeLikeIndex(best_attribute, "all", count, 0, children);
return no_leaf_node;
}
}
TreeLikeIndex::TreeLikeIndex(std::string attribute, std::string indices, int indices_count, short int is_leaf, unordered_map<std::string, TreeLikeIndex*> children)
{
this->attribute = attribute;
this->indices = indices;
this->is_leaf = is_leaf;
this->children = children;
this->children.clear();
for(pair<string, TreeLikeIndex*> p: children) this->children.insert(p);
this->indices_count = indices_count;
}
TreeLikeIndex::TreeLikeIndex(string indices, int indices_count)
{
this->indices = indices;
this->indices_count = indices_count;
this->is_leaf = 1;
}
TreeLikeIndex::TreeLikeIndex()
{
this->indices = "";
this->indices_count = 0;
this->is_leaf = 1;
}
int main()
{
string source_db_address = "my_table";
string table_name = "b";
string dest_folder_address = ".";
DecisionTreeLikeIndexer indexer(source_db_address, table_name, dest_folder_address);
indexer.rebuild_index();
}
And the output is:
Source table is: b Table count is: 9
Attributes list is: cant_n_dec cant_n_des cant_n_control
Entropy of node: 3.16993
Analysing attribute: cant_n_dec
Processing value: 1 With vSize: 1 Current WE is: 0
Processing value: 2 With vSize: 4 Current WE is: 0.888889
Processing value: 3 With vSize: 2 Current WE is: 1.11111
Processing value: 4 With vSize: 1 Current WE is: 1.11111
Processing value: 5 With vSize: 1 Current WE is: 1.11111
Finish computing WE for att: cant_n_dec Gain is: 2.05881
Found attribute with better gain.
Analysing attribute: cant_n_des
Processing value: 1 With vSize: 2 Current WE is: 0.222222
Processing value: 2 With vSize: 4 Current WE is: 1.11111
Processing value: 3 With vSize: 2 Current WE is: 1.33333
Processing value: 5 With vSize: 1 Current WE is: 1.33333
Finish computing WE for att: cant_n_des Gain is: 1.83659
Analysing attribute: cant_n_control
Processing value: 1 With vSize: 2 Current WE is: 0.222222
Processing value: 2 With vSize: 3 Current WE is: 0.750543
Processing value: 3 With vSize: 3 Current WE is: 1.27886
Processing value: 5 With vSize: 1 Current WE is: 1.27886
Finish computing WE for att: cant_n_control Gain is: 1.89106
Finish processing attributes list. Best attribute is: cant_n_dec Best gain is: 2.05881
Best attribute values are: 1,2,3,4,5,
Adding branch for val: 1
Next attributes are: cant_n_control,cant_n_des, Depth is: 1 Ids are: 3 Ids count: 1
Leaf at depth: 1 Ids are: 3 Ids count: 1
Segmentation fault
I'm not shure but....
I think the problem can be in the following cycle
for(;;)
{
int res = sqlite3_step(stmnt);
if(res == SQLITE_ROW)
{
string id = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmnt,0)));
if(!first) ids += "," + id;
else ids += id;
ids_count++;
}
if(res == SQLITE_DONE || res == SQLITE_ERROR)
{
Aux::tabs(depth+1);
cout << "Adding branch for val: " << val << endl;
Aux::tabs(depth+1);
cout << " Next attributes are: "; for_each(next_attributes_set.begin(), next_attributes_set.end(), [](string v){cout << v << ",";});
cout << " Depth is: " << next_depth << " Ids are: " << ids << " Ids count: " << ids_count << endl;
sqlite3_finalize(stmnt);
static TreeLikeIndex * temp_child = this->build_index(next_attributes_set, next_depth, ids, ids_count);
pair<string, TreeLikeIndex*> child (val, temp_child);
children.insert(child);
}
}
I don't understand when terminate (no exit conditions in the for(;;), no return's and no break's in the block).
And I suspect that che segmentation fault is caused by the following instruction
int res = sqlite3_step(stmnt);
when, after the SQLITE_DONE or SQLITE_ERROR case (whith a call to
sqlite3_finalize(stmnt);
), the cycle is iterated again, with a stmnt invalid.
The following can be a solution?
if ( sqlite3_prepare(this->source_db_connection, get_ids_of_bestatt_val.c_str(), -1, &stmnt,0) == SQLITE_OK)
{
while ( sqlite3_step(stmnt) == SQLITE_ROW )
{
ids += ( first ? "" : "," )
+ std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmnt,0)));
ids_count++;
}
Aux::tabs(depth+1);
cout << "Adding branch for val: " << val << endl;
Aux::tabs(depth+1);
cout << " Next attributes are: ";
for_each(next_attributes_set.begin(), next_attributes_set.end(), [](string v){cout << v << ",";});
cout << " Depth is: " << next_depth << " Ids are: " << ids << " Ids count: " << ids_count << endl;
sqlite3_finalize(stmnt);
static TreeLikeIndex * temp_child = this->build_index(next_attributes_set, next_depth, ids, ids_count);
pair<string, TreeLikeIndex*> child (val, temp_child);
children.insert(child);
}