Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is not possible with standard printf semantics. In, the past, I've had to do this by outputting to a string (with something like <code>"%.20f"</code>) then post-processing the string.</p> <p>Something like this is probably what you're looking for:</p> <pre><code>#include &lt;stdio.h&gt; void morphNumericString (char *s) { char *p; int count; // Find decimal point, if any. p = strchr (s,'.'); if (p == NULL) { // No decimal, just add one fractional position. strcat (s, ".0"); } else { // Decimal, start stripping off trailing zeros. while (s[strlen(s)-1] == '0') { s[strlen(s)-1] = '\0'; } // If all fractional positions were zero, add one. if (s[strlen(s)-1] == '.') { strcat (s, "0"); } } } </code></pre> <p>&nbsp;</p> <pre><code>int main (int argc, char *argv[]) { char str[100]; int i; for (i = 1; i &lt; argc; i++) { strcpy (str, argv[i]); morphNumericString (str); printf ("[%s] -&gt; [%s]\n", argv[i], str); } return 0; } </code></pre> <p>The code runs through each of it's arguments, morphing each one in turn. The following transcript shows how it works:</p> <pre><code>pax&gt; ./qq 3.750000 12 12.507 47.90 56.0000000 76.0 0 [3.750000] -&gt; [3.75] [12] -&gt; [12.0] [12.507] -&gt; [12.507] [47.90] -&gt; [47.9] [56.0000000] -&gt; [56.0] [76.0] -&gt; [76.0] [0] -&gt; [0.0] </code></pre> <p>You should be aware however that, if using floats or doubles, you'll have to watch out for the normal floating point inaccuracies. On my system 3.57 is actually 3.5699999999999998401, which won't be truncated at all.</p> <p>Of course, you can get around that problem by using a less-specific number of output digits in the <code>sprintf</code>, something less than the actual accuracy of the floating point point. For example, <code>"%.10f"</code> on my system outputs 3.5700000000 which <em>will</em> be truncated. Adding the following lines to <code>main</code>:</p> <pre><code>sprintf (str, "%.10f", 3.57); morphNumericString (str); printf ("[%.10f] -&gt; [%s]\n", 3.57, str); sprintf (str, "%.10f", 3.0); morphNumericString (str); printf ("[%.10f] -&gt; [%s]\n", 3.0, str); </code></pre> <p>will result in the following added output:</p> <pre><code>[3.5700000000] -&gt; [3.57] [3.0000000000] -&gt; [3.0] </code></pre> <p>as per your test data.</p> <p>One other possibility (if your input range and precision can be controlled) is to use the <code>g</code> format specifier. This outputs in either <code>f</code> format where the precision is the <em>maximum</em> number of digits (rather than fixed number like <code>f</code>) or exponential format (<code>e</code>).</p> <p>Basically, it prefers the non-exponential output format as long as all the information is shown. It will switch to exponential only if that will deliver more information. A simple example is the format string <code>"%.4g"</code> with <code>3.7</code> and <code>.0000000004</code>. The former would be printed as <code>3.7</code>, the latter as <code>4e-10</code>.</p> <hr> <p><em>Update:</em> for those more concerned about performance than robustness or readability, you could try the following (unnecessary in my opinion but to each their own):</p> <pre><code>void morphNumericString (char *s) { char *p = strchr (s,'.'); if (p == NULL) { strcat (s, ".0"); return; } p = &amp;(p[strlen(p)-1]); while ((p != s) &amp;&amp; (*p == '0') &amp;&amp; (*(p-1) != '.')) *p-- = '\0'; } </code></pre> <p>It <em>may</em> be faster but, given the extreme optimisations I've seen modern compilers do, you can never be too sure. I tend to code for readability first and only worry about speed when it becomes an issue (YAGNI can apply equally to performance as well as functionality).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload