Regex C Help on escape character - c++

I am having trouble extracting the token values from my string : "JOIN #ROOM\r\n"
I am compiling my code on Mingw64 with the following arguments : g++ tregex.cpp -o tregex.exe -std=gnu++11
I get this error , but not my exception for some reason :
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::regex_error'
what(): regex_error
This is my code :
#include <regex>
#include <string>
#include <iostream>
using namespace std;
//Tregex.cpp
int main(void) {
regex rgx("[[:cntrl:]]");
string str = "JOIN #ROOM\r\n";
smatch match;
try{
if(regex_search(str, match, rgx))
for(auto token:match) cout << token <<"\n";
cout<< endl;
}
catch(regex_error & e){
if( e.code() == regex_constants::error_escape )
cerr << "invalid escape character \n";
else if( e.code() == regex_constants::error_stack )
cerr << "regular expression is not big enough\n";
else
cerr << "exception caught: "<< e.what()<<"\n";
}
cin.get();
return 0;
}

FWIW, there's nothing wrong with your C++ code, and it works perfectly using Clang and libc++ on my MacBook.
As indicated by the comments above, <regex> is one of the features that works in the LLVM project's libc++ but has never worked properly in the GNU project's libstdc++. You might try switching to libc++ if it's available for your platform.

Related

Below regex in c++ is not working. Can you please explain why? [duplicate]

This question already has answers here:
Is gcc 4.8 or earlier buggy about regular expressions?
(3 answers)
Closed 5 years ago.
Below is the C++ program which uses regex to match a string, but is not working. My OS is Ubuntu Linux and compiler is standard C++ compiler which comes with ubuntu.
#include <iostream>
#include <regex>
using namespace std;
int main() {
const char s[] = "This is a target string";
regex e ("^([0-9a-zA-Z]*).*?");
cmatch matches;
if(regex_match(s, matches, e)) {
cout << "Match found" << endl;
for (int i = 0; i < matches.size(); ++i) {
cout << matches[i] << endl;
}
}
return 0;
}
On compiling using g++ like below
g++ -o test test.cpp -std=c++11
And running the program is failing with the below output
terminate called after throwing an instance of 'std::regex_error'
what(): regex_error
[1] 24898 abort (core dumped) ./test
The pattern is working fine and I tried it in rubular.com.I am expecting it to print
Match Found
This is a target string
This
I am new to using regular expressions in C++. Please point me in the right direction.
Can you use try/catch and catch the regex_error and print e.what() to know what excatly went wrong.
Btw, it worked perfectly with my gcc with c++11 flag
catch (const std::regex_error& e) {
std::cout << "regex_error caught: " << e.what() << '\n';
if (e.code() == std::regex_constants::error_brack) {
std::cout << "The code was error_brack\n";
}
}

C++: Issues with boost::filesystem on server (locale::facet::_S_create_c_locale name not valid)

i have a problem running my C++ project on our faculty server. The runtime error i get is this:
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
Aborted (core dumped)
I determined that the problem lies somewhere within this filesystem iterator (by utilizing a test program):
bf::path dir("ImageData/" + m_object_type);
vector<bf::path> tmp;
copy(bf::directory_iterator(dir), bf::directory_iterator(), back_inserter(tmp));
sort(tmp.begin(), tmp.end());
for (vector<bf::path>::const_iterator it(tmp.begin()); it != tmp.end(); ++it)
{
auto name = *it;
image_names.push_back(name.string());
}
The program ran perfectly on two other Linux-based system (kubuntu & linux mint, but as my project is quite runtime heavy and running it with different parameters would take about 28 days on my machine i really want to use the server). I already tried various paths but none of it worked. I read about a boost bug which led to this error before 1.47, but i'm using 1.54 on the server. I also checked the system locales but that doesn't really gave me a clue since they are almost similar to my system. The other specification of the server are:
Ubuntu 12.04.1 LTS (GNU/Linux 3.2.0-29-generic x86_64)
g/c++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
If anyone has any idea to share, i would appreciate it.
This is an issue with Boost < 1.56. Boost internally tries to construct a std::locale("") (see http://www.boost.org/doc/libs/1_55_0/libs/filesystem/src/path.cpp, and compare the updated version in v1.56). This call will fail if the locale (or LC_ALL) is invalid.
In my case, it was a call to boost::filesystem::create_directories() that triggered the locale("") call.
The following workaround worked for me: Override the LC_ALL environment variable in your program. std::locale("") seems to use that variable to determine what the “sensible default” locale should be.
#include <locale>
#include <cstdlib>
#include <iostream>
int main(int argc, char **)
{
try {
std::locale loc("");
std::cout << "Setting locale succeeded." << std::endl;
} catch (const std::exception& e) {
std::cout << "Setting locale failed: " << e.what() << std::endl;
}
// Set LC_ALL=C, the "classic" locale
setenv("LC_ALL", "C", 1);
// Second attempt now works for me:
try {
std::locale loc("");
std::cout << "Setting locale succeeded." << std::endl;
} catch (const std::exception& e) {
std::cout << "Setting locale failed: " << e.what() << std::endl;
}
}
After the setenv call, I can create a default locale, and the boost::filesystem calls work as well.
I don't know for sure, but I suspect that this program will behave the same:
#include <locale>
#include <iostream>
#include <stdexcept>
int main () {
try { std::locale foo (""); }
catch ( std::runtime_error & ex ) { std::cout << ex.what() << std::endl; }
}
Also, this (old) ticket https://svn.boost.org/trac/boost/ticket/5289 may shed some light on the subject.
EDIT: Technically, this is not an answer.
for anyone who is interested, here is a version of the above directory iterator utilizing the QT-lib:
string str1 = "ImageData/";
QString dir_string1 = QString::fromStdString(str1);
QString dir_string2 = QString::fromStdString(m_object_type);
dir_string1.append(dir_string2);
QDir dir(dir_string1);
dir.setFilter(QDir::Files);
dir.setSorting(QDir::Name);
QStringList entries = dir.entryList();
string tmp;
for (QStringList::ConstIterator it=entries.begin(); it != entries.end(); ++it)
{
auto name = *it;
tmp = name.toUtf8().constData();
image_names.push_back(str1 + m_object_type + "/" + tmp);
}

Regex error in C++

I have simple code which doesn't work. It throws this error: what(): regex_error and I have no idea why. Thanks for any help. I tried to compile it with this flag: -std=c++11.
#include <iostream>
#include <regex>
int main() {
std::regex r("[1-9]{4}");
std::cout << "result: " << std::regex_match("1524", r) << '\n';
return 0;
}

abort() called using std::regex to validate URL

#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main ()
{
if (std::regex_match ("http://www.google.com", std::regex("(http|https):\/\/(\w+\.)*(\w*)\/([\w\d]+\/{0,1})+")))
std::cout << "valid URL \n";
std::cout << std::endl;
return 0;
}
its compiling with the warnings ,but when I executed it gives
terminate called after throwing an instance of 'std::regex_error'
what(): regex_error
Aborted (core dumped)
what I should Do?
The warnings that you are ignoring are probably telling you what the problem is.
By looking at the pattern, you have not properly escaped the pattern string.
Properly escaping the pattern string to use '\' to escape the backslash will solve the problem. Otherwise, the compiler is tring to interpret the character that follows the un-escaped backslash into a string control character.
std::regex("(http|https)://(\\w+.)(\\w)/([\\w\\d]+/{0,1})+")
Try cpp-netlib:
#include <string>
#include <iostream>
#include <boost/network/uri.hpp>
int main (int argc, char ** argv)
{
std::string address = "http://www.google.com";
boost::network::uri::uri uri_(address);
if ( !boost::network::uri::valid(uri_) )
{
// error
std::cout << "not valid" << std::endl;
return 0;
}
std::cout << "valid" << std::endl;
std::string host = boost::network::uri::host(uri_);
std::string port = boost::network::uri::port(uri_);
std::string scheme = boost::network::uri::scheme(uri_);
return 0;
}
How to build (cpp-netlib is in /root/cpp-netlib-0.9.4/ in my case):
g++ main.cpp -L/root/cpp-netlib-0.9.4/libs/network/src/ -I/root/cpp-netlib-0.9.4/ -o main -lcppnetlib-uri -lboost_system

How to set the std::locale with gcc under cygwin?

I'm trying to make a simple program to enumerate the files on my disks, but I'm stuck at the great UTF frontier.
I'm using boost::recursive_directory_iterator to enumerate the files. That's works great, but Windows is set to "french canada" and many files and directories have french characters (likes é, è, ç). These filenames are not displayed correctly on the screen and I'm using wcout. I see a '▒' instead of the acute chars. Even boost::filesystem::ifstream is unable to open these files.
I tried to add "std::locale::global(std::locale(""))", but at first that only thrown an exception. I have found that when LANG is set to "" while executing the program, the previous command does not throw any more, but it only set the "C" locale instead of being the one use by the OS (which I expect to be "fr_CA.UTF-8" or "fr_CA.ISO8859-1"). Any other value for LANG bring the exception back...
What must be done to have a cygwin gcc program usable in an i18n world?
I have write this to test various locale ID:
#include <iomanip>
#include <iostream>
#include <locale>
using namespace std;
void tryLocale(string ID)
{
try{
cout << "Trying " << std::setw(18) << std::left << "\"" + ID + "\" ";
std::locale Loc(ID.c_str());
cout << "OK (" << Loc.name() << ")" << endl;
}catch(...){
cout << "FAIL" << endl;
}
}
const char *Locales[] = { "", "fr", "fr_CA", "fr_CA.UTF-8", "fr_CA.ISO8859-1", "C", 0};
int main()
{
cout << "Classic = " << std::locale::classic().name() << endl << endl;
int i = 0;
do
{ tryLocale(Locales[i]);
} while(Locales[++i]);
return 0;
}
And that gives me this output (without any LANG or LC_ALL):
Classic = C
Trying "" FAIL
Trying "fr" FAIL
Trying "fr_CA" FAIL
Trying "fr_CA.UTF-8" FAIL
Trying "fr_CA.ISO8859-1" FAIL
With LANG set to "", the first "trying" becomes
Trying "" OK (C)
The exception thrown print this:
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid