I've read a few StackExchange posts and other pages on converting strings to integers, but this is not working. This is the last thing I tried:
if (infile.is_open())
{
while (getline (infile,line))
{
regex_match(line,matches,exp);
regex_match((string)matches[1], time0, exp_time);
buffer << time0[1];
str = buffer.str();
str.append("\0");
cout << atoi(str.c_str()) << '\n';
last_match = matches[2];
buffer.str(string());
}
infile.close();
}
I can't think of any other ways. I tried the normal convert to string to char * to integer. I tried converting it to a string then using stoi() to convert it to an integer. I tried appending a NULL character ("\0") to it, I tried appending it in the buffer, too. I also tried atof() and stof(). stoi() and stof() both crash the program. atoi() and atof() both return 0, always.
Here's an SSCCE, with the problem featured (atoi(str.c_str())
should not be 0):
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
#include <sstream>
using namespace std;
int main(int argc, char* argv[])
{
regex exp("^(.+),(.+),.+,.+,(.+),.+,.+$");
regex exp_time("^(.+)-(.+)-(.+)");
smatch matches;
smatch time0;
string line;
ifstream infile(argv[1]);
string last_match;
stringstream buffer;
string str;
int i = 0;
if (infile.is_open())
{
while (getline(infile, line))
{
regex_match(line, matches, exp);
regex_match((string)matches[1], time0, exp_time);
buffer << time0[1];
str = buffer.str();
str = time0[1].str();
str.append("\0");
cout << atoi(str.c_str()) << " " << time0[1] << '\n';
last_match = matches[2];
buffer.str(string());
i++;
}
infile.close();
}
return 0;
}
The input would be a csv file with these values:
1996-09-04,19.00,19.25,18.62,18.87,528000,0.79
1996-09-03,19.00,19.37,18.75,19.00,1012800,0.79
1996-08-30,19.87,20.12,19.37,19.62,913600,0.82
1996-08-29,20.87,21.12,19.75,19.75,1987200,0.82
1996-08-28,20.12,22.12,20.12,21.12,5193600,0.88
1996-08-27,19.75,20.37,19.75,20.12,1897600,0.84
1996-08-26,20.12,20.12,19.75,19.75,388800,0.82
1996-08-23,19.75,20.25,19.75,19.75,1024000,0.82
1996-08-22,18.62,20.00,18.25,19.87,1921600,0.83
1996-08-21,19.12,19.25,18.25,18.62,688000,0.78
1996-08-20,19.62,19.62,19.12,19.12,494400,0.80
1996-08-19,19.37,19.62,19.37,19.62,428800,0.82
1996-08-16,19.50,19.87,19.12,19.37,864000,0.81
You would run the program with program.exe filename.csv
Here's a shorter program with the problems more apparent:
Your problem is in this line:
regex_match((string)matches[1], time0, exp_time);
You can't pass a temporary as the subject string of a regex match, because the string contents have to still be around when you query the match results. The result of (string)matches[1]
is destroyed at the end of the current full expression (i.e. at the next semicolon); when you get around to querying time0[1]
on the next line, the time0
match is referring to a string that doesn't exist any more, which is undefined behaviour.