2

I need to write several doubles in text file with dot separator. I know, that this code is the solution:

StreamWriter f = new StreamWriter(file, Encoding.ASCII, 128, false);
double a = 1.057887;
f.Write(a.ToString("G5", CultureInfo.InvariantCulture));

but I have too many numbers to write, so I tried method from this answer:

f.Write("{0:0.#####} {0:0.#####} {0:0.#####} {0:0.#####} {0:0.#####}", a, a, a, a, a));

and also tried to change the culture globally:

System.Threading.Thread.CurrentCulture.NumberFormat.NumberDecimalSeparator = ".";

But the first one '{0:0.#####}' resulted in comma separator (1,05789), and the second one 'Thread' in CS0120: An object reference is required for the non-static field, method, or property.

And another problem is that:

f.Write("{0:0.#####} {0:0.#####} ...", a, a, ...);

duplicates the first object after the string, so I get all of numbers as 'a', even if I write

f.Write("{0:0.#####} {0:0.#####} ...", a, b, ...);
Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
Perotto
  • 194
  • 1
  • 14
  • You need to create a new culture and you can use the current culture as a template and only change the separator – styx Oct 29 '19 at 07:56
  • _but I have too many numbers to write_ So? What makes you suspect you might have a performance issue?? Sounds like premature optimization to me.. – TaW Oct 29 '19 at 08:14
  • 'too many numbers' mean that I cannot cycle the ```f.Write(a.ToString("G5", CultureInfo.InvariantCulture));``` command, because it will generate me up to 8 lines of code instead of one ```f.Write("{0:0.#####} {0:0.#####} ...", a, a, ...);``` with all my parameters in line. It has nothing common with optimization, but with clear code. – Perotto Oct 29 '19 at 08:27

3 Answers3

1

You could use string.Format for that in a following way:

string.Format(CultureInfo.InvariantCluture, "{0:0.###} {0:0.#####}", a)
Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
1

You should be able to use string.Format and specify the appropriate CultureInfo in order to achieve this.

For example:

string.Format(CultureInfo.InvariantCulture, "{0:0.#####} {0:0.#####} {0:0.#####} {0:0.#####} {0:0.#####}", a, a, a, a, a)

Produces:

1.05789 1.05789 1.05789 1.05789 1.05789

Your file-writing code could become:

f.Write(string.Format(CultureInfo.InvariantCulture, "{0:0.#####} {0:0.#####} {0:0.#####} {0:0.#####} {0:0.#####}", a, a, a, a, a));
Martin
  • 16,093
  • 1
  • 29
  • 48
1

The problem with your last example:

f.Write("{0:0.#####} {0:0.#####} ...", a, b, ...);

Is that the part of the format strings before the colons is an index into the array of formatting parameters, so if you use all zeros, you will only get a, the 0'th parameter. Instead use

f.Write("{0:0.#####} {1:0.#####} ...", a, b, ...);

Here {1:0.#####} will use b, etc.

Unless your code is highly performance critical, my preferred way of formatting the strings in the invariant culture would be to use the method System.FormattableString.Invariant to do string interpolation in the invariant culture:

using static System.FormattableString;


...
f.Write(Invariant($"{a:G5} {b:G5} {c:G5} {d:G5}"));
...
Jonas Høgh
  • 10,358
  • 1
  • 26
  • 46