Why can I not convert this regex return to a string to an integer or straight to an integer? (C++)

atoi, c++, char, regex, string

Solution

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.

Problem

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:

Original source