Click here to Skip to main content
15,888,320 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I need to internationalisation an number in c++. Please give me a method to i18n an number, which accepts number as input parameter. I tried with below code but it returning junk value for Non-English domain.

What I have tried:

int CUGCell::FormatNumber(double number, long nbrDecs, char* destBuf, int bufSize)
{
	char		infoBuf[3];
	char		decimalSep[10];
	char		thousandSep[10];
	char		sourceNbr[50];
	NUMBERFMT*	customFormat = NULL;
	UINT		defDigits;
	LCID		lcid;
	int			status;

	lcid = GetUserDefaultLCID();

	status = GetLocaleInfo(lcid, LOCALE_IDIGITS, infoBuf, 3);
	if (status == 0){
		return status;
	}

	defDigits =  atoi(infoBuf);
	if (defDigits != (UINT) nbrDecs){
		customFormat = new NUMBERFMT;

		customFormat->NumDigits = nbrDecs;
		
		status = GetLocaleInfo(lcid, LOCALE_ILZERO, infoBuf, 3);
		customFormat->LeadingZero = atoi(infoBuf);

		status = GetLocaleInfo(lcid, LOCALE_SGROUPING, infoBuf, 3);
		customFormat->Grouping = atoi(infoBuf);

		status = GetLocaleInfo(lcid, LOCALE_STHOUSAND, thousandSep, 10);
		customFormat->lpThousandSep = thousandSep;

		status = GetLocaleInfo(lcid, LOCALE_SDECIMAL, decimalSep, 10);
		customFormat->lpDecimalSep = decimalSep;

 		status = GetLocaleInfo(lcid, LOCALE_INEGNUMBER, infoBuf, 3);
		customFormat->NegativeOrder = atoi(infoBuf);
	}
	customFormatConst = customFormat;

	//002 sprintf(sourceNbr, "%f", number);
	sprintf_s(sourceNbr, sizeof(sourceNbr),"%f", number);//002
	status = GetNumberFormat(lcid, 0, sourceNbr, customFormat, destBuf, bufSize);
	
	if (customFormat != NULL)
		delete customFormat;
	 
	return status; 
}
Posted
Updated 1-Mar-17 21:28pm
v2
Comments
Richard MacCutchan 2-Mar-17 3:00am    
It is impossible to guess what errors you see or where they occur. You need to use your debugger to step through the code and see what values are causing the problem.

1 solution

There are multiple errors within in your code.

The first is that you are using ANSI strings which will fail when having a Unicode build because that will return Unicode strings. Some info values are only provided as Unicode strings so that these will always fail.

The second error is initialising the global object customFormatConst with local data. The structure contains pointers to strings which are set to local buffers that go out of scope when leaving the function.

See also the GetLocaleInfo function (Windows)[^] (or use GetLocaleInfoEx function (Windows)[^]).

So you should use something like this:
// Global / static data
NUMBERFMT customFormatConst;
TCHAR thousandSep[10];
// ...

// Within function
TCHAR infoBuf[128];
status = GetLocaleInfo(lcid, LOCALE_IDIGITS, infoBuf, sizeof(infoBuf) / sizeof(TCHAR));
defDigits =  _tstoi(infoBuf);

status = GetLocaleInfo(lcid, LOCALE_STHOUSAND, thousandSep, sizeof(thousandSep) / sizeof(TCHAR));
customFormat->lpThousandSep = thousandSep;

// ...
// Copy to global data
if (customFormat)
    customFormatConst = *customFormat;


[EDIT]
If you want to specify the locale decimal point for the C standard printf functions there is a much simpler solution (especially when this should be applied to the whole application and not be changed multiple times).

Then call setlocale, _wsetlocale[^] at program start (main, InitInstance). To use the default locale settings for the user use
setlocale(LC_ALL, "");

To set the code page for a know LCID use
// Default system code page
char loc[16] = ".ACP";
// Try to get the default ANSI code page for the LCID
// Note that the ANSI function is called to get the result as char
//  and that it is stored after the '.' in the locale string
::GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, loc + 1, 15);
setlocale(LC_ALL, loc);


Note that the above changes all locale settings including dates, times, and collation order. If you only want to change the behaviour for numeric values use LC_NUMERIC isntead of LC_ALL.
[/EDIT]
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900