I have the following function:
Qt Code:
  1. string ldecimal(double x,double toler)
  2. {
  3. double x2;
  4. int h,i,iexp,chexp;
  5. size_t zpos;
  6. char *dotpos,*epos,*pLcNumeric;
  7. string ret,s,m,antissa,exponent,saveLcNumeric;
  8. char buffer[32],fmt[8];
  9. assert(toler>=0);
  10. pLcNumeric=getenv("LC_NUMERIC");
  11. if (pLcNumeric)
  12. saveLcNumeric=pLcNumeric;
  13. setenv("LC_NUMERIC","C",true);
  14. if (toler>0 && x!=0)
  15. {
  16. iexp=floor(log10(fabs(x/toler))-1);
  17. if (iexp<0)
  18. iexp=0;
  19. }
  20. else
  21. iexp=DBL_DIG-1;
  22. h=-1;
  23. i=iexp;
  24. while (true)
  25. {
  26. sprintf(fmt,"%%.%de",i);
  27. sprintf(buffer,fmt,x);
  28. x2=atof(buffer);
  29. if (h>0 && (fabs(x-x2)<=toler || i>=DBL_DIG+3))
  30. break;
  31. if (fabs(x-x2)>toler || i<=0)
  32. h=1;
  33. i+=h;
  34. }
  35. dotpos=strchr(buffer,'.');
  36. epos=strchr(buffer,'e');
  37. if (epos && !dotpos) // e.g. 2e+00 becomes 2.e+00
  38. {
  39. memmove(epos+1,epos,buffer+31-epos);
  40. dotpos=epos++;
  41. *dotpos=='.';
  42. }
  43. if (dotpos && epos)
  44. {
  45. m=string(buffer,dotpos-buffer);
  46. antissa=string(dotpos+1,epos-dotpos-1);
  47. exponent=string(epos+1);
  48. if (m.length()>1)
  49. {
  50. s=m.substr(0,1);
  51. m.erase(0,1);
  52. }
  53. iexp=atoi(exponent.c_str());
  54. zpos=antissa.find_last_not_of('0');
  55. antissa.erase(zpos+1);
  56. iexp=stoi(exponent);
  57. if (iexp<0 && iexp>-5)
  58. {
  59. antissa=m+antissa;
  60. m="";
  61. iexp++;
  62. }
  63. if (iexp>0)
  64. {
  65. chexp=iexp;
  66. if (chexp>antissa.length())
  67. chexp=antissa.length();
  68. m+=antissa.substr(0,chexp);
  69. antissa.erase(0,chexp);
  70. iexp-=chexp;
  71. }
  72. while (iexp>-5 && iexp<0 && m.length()==0)
  73. {
  74. antissa="0"+antissa;
  75. iexp++;
  76. }
  77. while (iexp<3 && iexp>0 && antissa.length()==0)
  78. {
  79. m+='0';
  80. iexp--;
  81. }
  82. sprintf(buffer,"%d",iexp);
  83. exponent=buffer;
  84. ret=s+m;
  85. if (antissa.length())
  86. ret+='.'+antissa;
  87. if (iexp)
  88. ret+='e'+exponent;
  89. }
  90. else
  91. ret=buffer;
  92. setenv("LC_NUMERIC",saveLcNumeric.c_str(),true);
  93. return ret;
  94. }
To copy to clipboard, switch view to plain text mode 
The function is used to format numbers when writing to files, so it has to use '.' for the decimal point regardless of locale. I added the saving and restoring LC_NUMERIC code to fix this bug. It didn't work.

I am using it in at least two programs: bezitest, which is a non-Qt test program, and viewtin, which is a Qt GUI program. Until I implement hit-testing, viewtin is displaying the coordinates of the cursor in world space. "bezitest ldecimal" outputs, among others, "3.141592653589793". viewtin displays a tooltip saying something like "3,141592653589793,2,718281828459045". I ran it in gdb and found that the comma is put there by sprintf.

locale outputs the following:
Qt Code:
  1. LANG=en_DK.UTF-8
  2. LANGUAGE=en_US:es
  3. LC_CTYPE="en_DK.UTF-8"
  4. LC_NUMERIC="en_DK.UTF-8"
  5. LC_TIME="en_DK.UTF-8"
  6. LC_COLLATE="en_DK.UTF-8"
  7. LC_MONETARY="en_DK.UTF-8"
  8. LC_MESSAGES="en_DK.UTF-8"
  9. LC_PAPER="en_DK.UTF-8"
  10. LC_NAME="en_DK.UTF-8"
  11. LC_ADDRESS="en_DK.UTF-8"
  12. LC_TELEPHONE="en_DK.UTF-8"
  13. LC_MEASUREMENT="en_DK.UTF-8"
  14. LC_IDENTIFICATION="en_DK.UTF-8"
  15. LC_ALL=
To copy to clipboard, switch view to plain text mode 
LC_NUMERIC is actually unset.