Set locale to avoid numeric conversion issues

In certain locales decimal separator is comma instead of a dot.
Without this change OpenALPR will silently fail or produce
meaningless error from underlying OpenCV function.

Additionally json produced will not be valid.
This commit is contained in:
Artur Bańkowski
2016-09-26 21:08:49 +02:00
parent 583f69acac
commit 0f07bba7dd
2 changed files with 22 additions and 4 deletions

View File

@@ -30,6 +30,7 @@
#include <float.h> #include <float.h>
#include <limits.h> #include <limits.h>
#include <ctype.h> #include <ctype.h>
#include <locale.h>
#include "cjson.h" #include "cjson.h"
static const char *ep; static const char *ep;
@@ -117,6 +118,9 @@ static const char *parse_number(cJSON *item,const char *num)
/* Render the number nicely from the given item into a string. */ /* Render the number nicely from the given item into a string. */
static char *print_number(cJSON *item) static char *print_number(cJSON *item)
{ {
char * locale = setlocale(LC_ALL, NULL);
setlocale(LC_NUMERIC, "C");
char *str; char *str;
double d=item->valuedouble; double d=item->valuedouble;
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
@@ -134,6 +138,8 @@ static char *print_number(cJSON *item)
else sprintf(str,"%f",d); else sprintf(str,"%f",d);
} }
} }
setlocale(LC_NUMERIC, locale);
return str; return str;
} }

View File

@@ -19,6 +19,7 @@
#include "config_helper.h" #include "config_helper.h"
#include <clocale>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
@@ -37,7 +38,13 @@ namespace alpr
return defaultValue; return defaultValue;
} }
char * locale = std::setlocale(LC_ALL, NULL);
setlocale(LC_NUMERIC, "C");
float val = atof(pszValue); float val = atof(pszValue);
std::setlocale(LC_NUMERIC, locale);
return val; return val;
} }
@@ -52,12 +59,17 @@ namespace alpr
std::vector<float> response; std::vector<float> response;
char * locale = std::setlocale(LC_ALL, NULL);
std::setlocale(LC_NUMERIC, "C");
// output all of the items // output all of the items
CSimpleIniA::TNamesDepend::const_iterator i; CSimpleIniA::TNamesDepend::const_iterator i;
for (i = values.begin(); i != values.end(); ++i) { for (i = values.begin(); i != values.end(); ++i) {
response.push_back(atof(i->pItem)); response.push_back(atof(i->pItem));
} }
std::setlocale(LC_NUMERIC, locale);
return response; return response;
} }