ICU’s MessageFormat class can be used to format messages in a locale-independent manner to localize the user interface (UI) strings.
C++
/* The strings below can be isolated into a resource bundle
* and retrieved dynamically
*/#define LANGUAGE_NAMES "{0}<{1}languages {2}>\n"
#define LANG_ATTRIB "{0}<language id=\"{1}\" >{2}</language>\n"
#define MONTH_NAMES "{0}<monthNames>\n"
#define END_MONTH_NAMES "{0}</monthNames>\n"
#define MONTH "{0}<month id=\"{1}\">{2}</month>\n"
#define MONTH_ABBR "{0}<monthAbbr>\n"
#define END_MONTH_ABBR "{0}</monthAbbr>\n"
UnicodeStringCXMLGenerator::formatString(UnicodeString&str,UnicodeString&argument){Formattableargs[]={argument};UnicodeStringresult;MessageFormatformat(str,mError);FieldPositionfpos=0;format.format(args,1,result,fpos,mError);if(U_FAILURE(mError)){returnUnicodeString("Illegal argument");}returnresult;}voidCXMLGenerator::writeLanguage(UnicodeString&xmlString){UnicodeString*itemTags,*items;char*key="Languages";int32_tnumItems;if(U_FAILURE(mError)){return;}mRBundle.getTaggedArray(key,itemTags,items,numItems,mError);if(mError!=U_USING_DEFAULT_ERROR&&U_SUCCESS(mError)&&mError!=U_ERROR_INFO_START){Formattableargs[]={indentOffset,"",""};xmlString=formatString(UnicodeString(LANGUAGE_NAMES),args,3);indentOffset.append("\t");for(int32_ti=0;i<numItems;i++){args[0]=indentOffset;args[1]=itemTags[i];args[2]=items[i];xmlString.append(formatString(UnicodeString(LANG_ATTRIB),args,3));}chopIndent();args[0]=indentOffset;args[1]=(UnicodeString(XML_END_SLASH));args[2]="";xmlString.append(formatString(UnicodeString(LANGUAGE_NAMES),args,3));return;}mError=U_ZERO_ERROR;xmlString.remove();}voidCXMLGenerator::writeMonthNames(UnicodeString&xmlString){int32_tlNum;constUnicodeString*longMonths=mRBundle.getStringArray("MonthNames",lNum,mError);if(mError!=U_USING_DEFAULT_ERROR&&mError!=U_ERROR_INFO_START&&mError!=U_MISSING_RESOURCE_ERROR){xmlString.append(formatString(UnicodeString(MONTH_NAMES),indentOffset));indentOffset.append("\t");for(inti=0;i<lNum;i++){charc;itoa(i+1,&c,10);Formattableargs[]={indentOffset,UnicodeString(&c),longMonths[i]};xmlString.append(formatString(UnicodeString(MONTH),args,3));}chopIndent();xmlString.append(formatString(UnicodeString(END_MONTH_NAMES),indentOffset));mError=U_ZERO_ERROR;return;}xmlString.remove();mError=U_ZERO_ERROR;}
C
voidmsgSample1(){UChar*result,*tzID,*str;UCharpattern[100];int32_tresultLengthOut,resultlength;UCalendar*cal;UDated1;UErrorCodestatus=U_ZERO_ERROR;str=(UChar*)malloc(sizeof(UChar)*(strlen("disturbance in force")+1));u_uastrcpy(str,"disturbance in force");tzID=(UChar*)malloc(sizeof(UChar)*4);u_uastrcpy(tzID,"PST");cal=ucal_open(tzID,u_strlen(tzID),"en_US",UCAL_TRADITIONAL,&status);ucal_setDateTime(cal,1999,UCAL_MARCH,18,0,0,0,&status);d1=ucal_getMillis(cal,&status);u_uastrcpy(pattern,"On {0, date, long}, there was a {1} on planet{2,number,integer}");resultlength=0;resultLengthOut=u_formatMessage("en_US",pattern,u_strlen(pattern),NULL,resultlength,&status,d1,str,7);if(status==U_BUFFER_OVERFLOW_ERROR){status=U_ZERO_ERROR;resultlength=resultLengthOut+1;result=(UChar*)realloc(result,sizeof(UChar)*resultlength);u_formatMessage("en_US",pattern,u_strlen(pattern),result,resultlength,&status,d1,str,7);}printf("%s\n",austrdup(result));//austrdup( a function used to convertUChar*tochar*)free(tzID);free(str);free(result);}char*austrdup(constUChar*unichars){intlength;char*newString;length=u_strlen(unichars);newString=(char*)malloc(sizeof(char)*4*(length+1));if(newString==NULL)returnNULL;u_austrcpy(newString,unichars);returnnewString;}Thisisamorepracticalsamplewhichretrievesdatafromaresourcebundleandfeedsthedatatou_formatMessagetoproduceaformattedstringvoidmsgSample3(){char*key="Languages";int32_tnumItems;/* This constant string can also be in the resouce bundle and retrieved at
the time
* of formatting
* eg:
* UResouceBundle* myResB = ures_open("myResources",currentLocale,&err);
* UChar* Lang_Attrib = ures_getString(myResb,"LANG_ATTRIB",&err);
*/UChar*LANG_ATTRIB=(UChar*)"{0}<language id=\"{1}\">{2}</language>\n";UChar*result;UResourceBundle*pResB,*pDeltaResB=NULL;UErrorCodeerr=U_ZERO_ERROR;UChar*indentOffset=(UChar*)"\t\t\t";pResB=ures_open("","en",&err);if(U_FAILURE(err)){return;}ures_getByKey(pResB,key,pDeltaResB,&err);if(U_SUCCESS(err)){constUChar*value=0;constchar*key=0;int32_tlen=0;int16_tindexR=-1;int32_tresultLength=0,resultLengthOut=0;numItems=ures_getSize(pDeltaResB);for(;numItems-->0;){key=ures_getKey(pDeltaResB);value=ures_get(pDeltaResB,key,&err);resultLength=0;resultLengthOut=u_formatMessage("en_US",LANG_ATTRIB,u_strlen(LANG_ATTRIB),NULL,resultLength,&err,indentOffset,value,key);if(err==U_BUFFER_OVERFLOW_ERROR){err=U_ZERO_ERROR;resultLength=resultLengthOut+1;result=(UChar*)realloc(result,sizeof(UChar)*resultLength);u_formatMessage("en_US",LANG_ATTRIB,u_strlen(LANG_ATTRIB),result,resultLength,&err,indentOffset,value,key);printf("%s\n",austrdup(result));}}return;}err=U_ZERO_ERROR;}
Java
importcom.ibm.icu.text.*;importjava.util.Date;importjava.text.FieldPosition;publicclassTestMessageFormat{publicvoidrunTest(){Stringformat="At {1,time,::jmm} on {1,date,::dMMMM}, there was {2} on planet {3,number,integer}.";MessageFormatmf=newMessageFormat(format);ObjectobjectsToFormat[]={newDate(System.currentTimeMillis()),newDate(System.currentTimeMillis()),"a Disturbance in the Force",newInteger(5)};FieldPositionfp=newFieldPosition(1);StringBuffersb=newStringBuffer();try{sb=mf.format(objectsToFormat,sb,fp);System.out.println(sb.toString());}catch(IllegalArgumentExceptione){System.out.println("Exception during formatting of type :"+e);}}publicstaticvoidmain(Stringargs[]){try{newTestMessageFormat().runTest();}catch(Exceptione){System.out.println("Exception of type: "+e);}}}
ChoiceFormat Class
Important: The following documentation is outdated. ChoiceFormat is probably not what you need. Please use MessageFormat with plural arguments for proper plural selection, and select arguments for simple selection among a fixed set of choices!
ICU’s ChoiceFormat class provides more flexibility than the printf() and scanf() style functions for formatting UI strings. This interface can be useful if you would like a message to change according to the number of items you are displaying.
Note: Some Asian languages do not have plural words or phrases.
C++
voidmsgSample1(){UChar*result,*tzID,*str;UCharpattern[100];int32_tresultLengthOut,resultlength;UCalendar*cal;UDated1;UErrorCodestatus=U_ZERO_ERROR;str=(UChar*)malloc(sizeof(UChar)*(strlen("disturbance in force")+1));u_uastrcpy(str,"disturbance in force");tzID=(UChar*)malloc(sizeof(UChar)*4);u_uastrcpy(tzID,"PST");cal=ucal_open(tzID,u_strlen(tzID),"en_US",UCAL_TRADITIONAL,&status);ucal_setDateTime(cal,1999,UCAL_MARCH,18,0,0,0,&status);d1=ucal_getMillis(cal,&status);u_uastrcpy(pattern,"On {0, date, long}, there was a {1} on planet{2,number,integer}");resultlength=0;resultLengthOut=u_formatMessage("en_US",pattern,u_strlen(pattern),NULL,resultlength,&status,d1,str,7);if(status==U_BUFFER_OVERFLOW_ERROR){status=U_ZERO_ERROR;resultlength=resultLengthOut+1;result=(UChar*)realloc(result,sizeof(UChar)*resultlength);u_formatMessage("en_US",pattern,u_strlen(pattern),result,resultlength,&status,d1,str,7);}printf("%s\n",austrdup(result));//austrdup( a function used to convertUChar*tochar*)free(tzID);free(str);doublefilelimits[]={0,1,2};UErrorCodeerr;UnicodeStringfilepart[]={"are no files","is one file","are {2} files"};ChoiceFormatfileform(filelimits,filepart,err);FormattestFormats[]={fileform,null,NumberFormat.getInstance()};MessageFormatpattform("There {0} on {1}",err);pattform.setFormats(testFormats);FormattabletestArgs[]={null,"ADisk",null};for(inti=0;i<4;++i){testArgs[0]=i;testArgs[2]=testArgs[0];FieldPositionfpos=0;format.format(args,1,result,fpos,mError);UnicodeStringresult=pattform.format(testArgs);}
C
voidmsgSample2(){UChar*str;UErrorCodestatus=U_ZERO_ERROR;UChar*result;UCharpattern[100];int32_tresultlength,resultLengthOut,i;doubletestArgs[3]={100.0,1.0,0.0};str=(UChar*)malloc(sizeof(UChar)*10);u_uastrcpy(str,"MyDisk");u_uastrcpy(pattern,"The disk {1} contains {0,choice,0#no files|1#onefile|1<{0,number,integer} files}");for(i=0;i<3;i++){resultlength=0;resultLengthOut=u_formatMessage("en_US",pattern,u_strlen(pattern),NULL,resultlength,&status,testArgs[i],str);if(status==U_BUFFER_OVERFLOW_ERROR){status=U_ZERO_ERROR;resultlength=resultLengthOut+1;result=(UChar*)malloc(sizeof(UChar)*resultlength);u_formatMessage("en_US",pattern,u_strlen(pattern),result,resultlength,&status,testArgs[i],str);}}printf("%s\n",austrdup(result));//austrdup( a function used toconvertUChar*tochar*)free(result);}
Java
importjava.text.ChoiceFormat;importcom.ibm.icu.text.*;importjava.text.Format;publicclassTestChoiceFormat{publicvoidrun(){double[]filelimits={0,1,2};String[]filepart={"are no files","is one file","are {2} files"};ChoiceFormatfileform=newChoiceFormat(filelimits,filepart);Format[]testFormats={fileform,null,NumberFormat.getInstance()};MessageFormatpattform=newMessageFormat("There {0} on {1}");Object[]testArgs={null,"ADisk",null};for(inti=0;i<4;++i){testArgs[0]=newInteger(i);testArgs[2]=testArgs[0];System.out.println(pattform.format(testArgs));}}publicstaticvoidmain(Stringargs[]){newTestChoiceFormat().run();}}