CString formatting currency - mfc

Good evening, could you tell me if a class or a method exists in MFC visual C++ which takes a CString type and formats it in currency… i.e CString str; str = _T("12345,67") and str becomes= 12.345,67 or str = 5000 and becomes str = 5.000,00
I've also tried to create a method but without success
Thanks who will be able to help me… I know it would be easier to add the points as separators where it needs, but when I need to convert the CString in double it truncates from the first point to the end.
I don't have a solution

I suggest that you use the GetCurrencyFormatEx function for this.
To quote the article:
Formats a number string as a currency string for a locale specified by name.
As for COleCurrency, you are not left to work it out for yourself. There is documentation. I admit I have not used this class, but it implies that COleCurrency::Format will do what you want:
Returns a CString that contains the formatted currency value.
Sample code is provided:
COleCurrency curA; // value: 0.0000
curA.SetCurrency(4, 500); // value: 4.0500
// value returned: 4.05
curA.Format(0, MAKELCID(MAKELANGID(LANG_CHINESE,
SUBLANG_CHINESE_SINGAPORE), SORT_DEFAULT));
// value returned: 4,05
curA.Format(0, MAKELCID(MAKELANGID(LANG_GERMAN,
SUBLANG_GERMAN_AUSTRIAN), SORT_DEFAULT));
ParseCurrency is also documented and again, a sample is provided:
// works if default locale has dot decimal point
COleCurrency cur;
cur.ParseCurrency(_T("$135.95"), 0);
ASSERT(cur == COleCurrency(135, 9500));

Related

Ogre3d having unique node names error

I am working on city generation for a pcg game of mine. I have a for loop which makes 3 cities in random locations, I assign parentIteration to get that "id" for the city and do the same in the for loop where I make a building
for (int i = 0; i < 3; i++)
{
parentIteration = i;
std::srand(i);
_rootNode = GameManager::getSingletonPtr()->getSceneManager()->getRootSceneNode();
_cityNode = _rootNode->createChildSceneNode("cityNode " + parentIteration);
generateCity(std::rand() % 10000 + 10, std::rand() % 10000 + 10, std::rand() % 11 +1);
}
building
for (int i = 0; i < _numberOfBuildings; i++)
{
childIteration = i;
printf(" parent %d and child %d \n", parentIteration, childIteration);
Ogre::SceneNode* buildingNode = _cityNode->createChildSceneNode("citybuildingNode"+childIteration+parentIteration );
}
However when I try to launch the game it will crash on creating the second city. Saying it already has a name similar to what it is trying to write. Yet my printf clearly show that the numbers at that point are all unique. Anyone know how to resolve this issue? (added picture for proof of output)
The "itybuildingNode" in the error message suggests that
"citybuildingNode"+childIteration+parentIteration
is not working quite the way you wanted.
This is because of a couple things working against you:
"citybuildingNode" is a String Literal, and not a string object. It is litteraly just a bunch of characters in a row terminated by a null character and represented as a const char *, a pointer to that array of characters. It is low-level voodoo, the sort of stuff you might make a string class around. For more information see String Literals
Because it's not a string object, you can't pull any of the usual string object tricks like concatenating with a + and comparing with ==. But because it is a pointer, the compiler interprets + as an attempt to perform pointer arithmetic and reference another location in the array. It compiles, but note how it turned "citybuildingNode" into "itybuildingNode". Oops.
What this looks like is something like:
const char* temp = "citybuildingNode"
_cityNode->createChildSceneNode(temp + childIteration + parentIteration);
which resolves to
const char* temp = "citybuildingNode"
_cityNode->createChildSceneNode(&temp[childIteration + parentIteration]);
Even if it was a string object, the C++ standard string object, std::string does not allow you to add numbers to strings. It only adds strings together to build a bigger string. To add a number to a std::string, you have to turn the number into a std::string. std::to_string can help you here, but there is a cleaner-looking way to do this with std::stringstream
Eg:
std::stringstream nodename("citybuildingNode");
// builds a string stream around the string literal
nodename << childIteration << parentIteration;
// writes the numbers into the stream the same way `cin << number;` would
// turning the number into a string for you
Ogre::SceneNode* buildingNode = _cityNode->createChildSceneNode(nodename.str());
// gets the assembled string from the stringstream
// null-terminated string like ogre expects
This gets you started in the right direction, but still allows for collision between child 1 and parent 10 ("citybuildingNode110") and child 11 and parent 0 (also "citybuildingNode110") and similar. So you really want something more like
nodename << childIteration << '_' << parentIteration;
to force a separator between the two numbers.
Documentation for std::stringstream.
There is also another possible nasty. The string we just supplied to ogre will only exist for as long as std::stringstream nodename exists and it will die at the end of the loop that generates it. I do not see anything in a quick perusal of the documentation that says ogre makes its own copy of this string. So play around a bit to make sure that you don't have to store this name somewhere to prevent it from falling out of scope, being destroyed, and leaving ogre with a dangling reference.

Cast a string from Glib::ustring to double - gtkm 2

I am developing an c++ app in gtkmm 2
I have a problem to cast the string from an entryfield to a double (or int).
I get the following compilation error
cannot convert from Glib::ustring to double
The entryfield
interestrate.set_max_length(50);
interestrate.set_text(interestrate.get_text() );
interestrate.select_region(0, interestrate.get_text_length());
m_box1.pack_start(interestrate);
interestrate.show();
the button
m_button3.signal_clicked().connect(sigc::bind<-1, Glib::ustring>(
sigc::mem_fun(*this, &HelloWorld::on_button_clicked), "OK"));
m_box1.pack_start(m_button3);
m_button3.show();
and the eventhandler
void HelloWorld::on_button_clicked(Glib::ustring data)
{
std::cout << "interestrate: " << interestrate.get_text() << std::endl;
}
so i want to get a double of the returnvalue from
interestrate.get_text()
I didnt beleive it could be so easy
std::string s = interestrate.get_text();
double d = atof(s.c_str());
Your suggestion would work for valid C locale input.
If you want to deal with bad number formats and locale considerations you have to do a little bit more; atof returns 0 on error, but 0 may be a valid input, and here in Germany users would perhaps enter a comma as the decimal point.
I would think (from reading the glib docs and this answer: How can I convert string to double in C++?), that you should get the proper localized std::string first via Glib::locale_from_utf8() and then create a stringstream from that and read your double out of that. The stream gives you error information and the conversion/operator>>() will deal with locale issues if you have "imbued" a locale.

libjson parses integers incorrectly

I am trying to parse following JSON data (created with JSON.stringify). I am using libJSON 7. My code follows:
wstring jsonstr = _T("{\"Id\":0,\"Note\":\"\",\"Username\":\"user\",\"Password\":\"pass\",\"Enabled\":true,\"ProfileId\":\"\",\"UserAgent\":\"\",\"LastUsage\":0,\"Failures\":0,\"Abuses\":0}");
JSONNode jsondata = libjson::parse(jsonstr);
auto i = jsondata.begin();
auto num = i->as_float();
int idIsNan = _isnan(num);// Nonzero here
Now I expect that num == (double)0, however, it equals 1.#QNAN00000000000 instead. Does anyone know how to bypass this bug?
Also if I use as_int instead of as_float, it parses data correctly; so, it looks like this bug takes place for as_float method only.
I am guessing a bit here, since you don't show all the relevant code:
Your json structure is data, json seems to be the string you are parsing. So json.begin() would be the first character in that string, not the first json value. Since that first character is double quote, it cannot be parsed as a float -> you get the nonsense you see. Maybe this is what you want:
JSONNode data = libjson::parse(json);
auto i = data.begin(); //<-- data, not json!
auto num = i->as_float();
Please remember to give all the relevant code next time, that includes definition of all used variables (in this case, 'json').
PS: The json string you posted ends with an unmatched } - that might confuse the parser.

C++ regex, parsing

I'm pretty new with regexp and I can't get my function doing what I would like.
I have a long string, and I want to extract from it, 3 variables.
My string looks :
Infoname/info :
Input_Device_Name GTape Buffer_Size 16384 Acquisition_Event_Rate 163691.000000
Acquisition_Buffer_Rate 14873.333008 Acquisition_Succes_Rate 100.000000
And my goal is to store 163691.000000, 14873.333008 and 100.000000 in three differents variables.
What is the fastest and nicest way to do it please ?
Thank you,
eo
You could use the following regex to look for it:
"Input_Device_Name\s+GTape\s+Buffer_Size\s+[0-9.]+\s+Acquisition_Event_Rate\s+([0-9.]+)\s+Acquisition_Buffer_Rate\s+([0-9.]+)\s+Acquisition_Succes_Rate\s+([0-9.]+)"
This should catch the three values assuming that your text stays the same and that your numbers always take this form (i.e. are positive and not in exponential form.) Note that only the last three numbers are captured by putting brackets round them.
If you use boost regex, you could do something like this:
#include <boost/regex.hpp>
...
boost::smatch what;
static const boost::regex pp("Input_Device_Name\\s+GTape\s+Buffer_Size\\s+[0-9.]+\\s+Acquisition_Event_Rate\\s+([0-9.]+)\\s+Acquisition_Buffer_Rate\\s+([0-9.]+)\\s+Acquisition_Succes_Rate\\s+([0-9.]+)");
if ( boost::regex_match(inputTextString, what, pp) )
{
if ( what.size() == 4 )
{
double d1 = strtod(static_cast<const string&>( what[1] ).c_str(), NULL, 0);
double d2 = strtod(static_cast<const string&>( what[2] ).c_str(), NULL, 0);
double d3 = strtod(static_cast<const string&>( what[3] ).c_str(), NULL, 0);
// These are your doubles, do some stuff with them.
}
}
Where inputTextString contains the line of text you want to parse, so if this is coming from a file say, you would want to place this code in a loop. The what variable is a vector of all the matching text though what[0] contains the whole line and so can be ignored unless you need it. Last but not least, remember to double escape the 'space' character class otherwise it will already be processed (or generate an error or warning) by the compiler prior to being presented to the regex processor. Also, please note that I've not had time to compile this, though it is based on working code
Watch out for trailing, leading space on your input file and use ^ and $ to mark the beginning or end of the line respectively if it helps.
Just search for [0-9\.]+ as long as it returns any results. And, for example, if you would like to refuse 16384 as a variable you don't need, test every search result for having a dot in it.

How can I find the type of the value present in vector of type string?

I have a config file:
#X,Name,hostid,processid,executecommand,Max Runs, Max failure time
X,Main_XYZ_service,1,1,/opt/bada/bin,3,6,300
I parsed the above config file and stored each of the values in a vector of type string.
This is stored in vector<string> scanned:
//scanned[0]=X
//scanned[1]=Main_XYZ_service.........
long H_hostid = atoi(scanned[5].c_str());
how can I detect the type of the elements present in the vector?
If I call atoi() with a string that doesn't have a number, atoi() returns 0, but it also returns 0 if the string contains the number 0. How can I correctly assign a value to H_hostid?
In an absolute sense, you can't. If you encounter the string "0", you
can't know whether the user intended a string, an integer or a floating
point value. On the other hand, if you know what you need, you can try
to convert (say by using boost::lexical_cast), and generate an error
if it doesn't match. Alternatively, you can use regular expressions for
pattern matching, and decide what type you want as a result of what
pattern matches.
For a configuration file, I'd suggest the former. Just keep everything
as a string until you know what you need, then try the conversion (using
something reasonable for the conversion, which will report an error, and
not atoi).
Don't use atoi() - as you say, there is no way to detect errors. Use std::istringstream in C++, or strtol() in C.
long H_hostid;
std::istringstream stream(scanned[5]);
if (!(stream >> H_hostid)) {
// handle error
}
You could also use boost::lexical_cast, which does the same thing as that example, and throws an exception if the conversion fails.
If this is the data stored as a single string:
X,Main_XYZ_service,1,1,/opt/bada/bin,3,6,300
then the solution is, split this string using , as separator, and store each token in an array of size 8, then you can interpret each token based on the index as shown below:
char,string, int, int, string, int, int, int
0 1 2 3 4 5 6 7
Code would look like this:
std::string s = "X,Main_XYZ_service,1,1,/opt/bada/bin,3,6,300";
std::vector<std::string> tokens = split(s); //write the function yourself!
char c = tokens[0]; //token with index 0 is char
std::string service = tokens[1]; //token with index 1 is string
std::string path = tokens[4]; //token with index 4 is string
int int_indices[] = {2,3,5,6,7}; //rest of the index has int : total 5
for(int i = 0 ; i < 5 ; i++ )
{
try
{
int value = boost::lexical_cast<int>(tokens[int_indices[i]]);
//store value
}
catch(const bad_lexical_cast &)
{
std::cout << tokens[int_indices[i]] <<" is not an int" << std::endl;
}
}
Whenever you write a config file to be used by your application, you know in advance in what order the values will appear in that file. Otherwise, an xml or key value coding will be a better option to write a config file for general case. Personally, I would never create a config file as you have shown in your example.