-1

Assume we want to remove the last unwanted , in the following code.

for (int i = 0; i < 5; i++)
{
    foreach (var a in "Money")
        Console.Write($"{a},");
}

enter image description here

If we only add Console.Write("\b\n"); as follows,

for (int i = 0; i < 5; i++)
{
    foreach (var a in "Money")
        Console.Write($"{a},");
    Console.Write("\b\n");
}

The output will be still the same. The unwanted trailing comma still exists.

But if we add \0 as follows,

for (int i = 0; i < 5; i++)
{
    foreach (var a in "Money")
        Console.Write($"{a},");
    Console.Write("\b\0\n");
} 

The unwanted trailing , vanishes.

enter image description here

Someone said that using \0 is just a hack that might break in the future updates. So, what is the correct and safe way to remove the trailing comma if I insist on using \b\n sequence?

Edit

Not only on the terminal output, \b in the following does not remove the previous character.

using (StreamWriter sw = new StreamWriter("output.txt"))
{
    for (int i = 0; i < 5; i++)
    {
        foreach (var a in "Money")
            sw.Write($"{a},");
        sw.Write("\b\n");
    }
}
Second Person Shooter
  • 14,188
  • 21
  • 90
  • 165
  • 1
    Generally when I need to write something with a delimiter I'll write it before each item after the first so I don't need to worry about the end. – Retired Ninja Jun 30 '20 at 08:46
  • Is there a real issue behind this? You could use a library like CsvHelper to generate CSV files with a few lines. You could use StringBuilder instead of writing directly to the console and just remove the trailing character after each iteration. There are similar questions for both scenarios – Panagiotis Kanavos Jun 30 '20 at 08:48
  • 2
    `why \b\n does not work.` to do what? How that behaves depends on the *console* you use, and the old Windows console was pretty limited. Windows Terminal understands full ANSI escape sequences to move the cursor around, change colours, add shadows etc. Of course, it's better to just *not* emit text you don't won't – Panagiotis Kanavos Jun 30 '20 at 08:50
  • As Panagiotis Kanavos said, these escape sequence are very terminal-dependent. I'm using the macOS Terminal and `\b\0\n` still gives me the trailing commas. – Sweeper Jun 30 '20 at 08:54
  • 1
    No, you still haven't explained what the point is. Console/screen escape sequences don't help when you want to generate a CSV file or string that behaves a certain way. Erasing text on the screen is wasteful and guaranteed to cause problems if you redirect that output to another program. The next program will see the individual characters, not the final screen. It will see the original text followed by a `\b ` character – Panagiotis Kanavos Jun 30 '20 at 08:54
  • `\0` is hacky as i don't even know what it is. anyway if you simply want to remove it, then do a sub-string and remove the last char...? or only add `,` when not last, you would need to count the length.. to know when last. i tend to agree with @PanagiotisKanavos, what is the point... if its only for console. – Seabizkit Jun 30 '20 at 08:55
  • If you really wanted to control the terminal, you should use [ANSI escape sequences](https://en.wikipedia.org/wiki/ANSI_escape_code) These work on all Mac, Linux terminals and Windows Terminal but not the old console. You could even use [gui.cs](https://github.com/migueldeicaza/gui.cs) to create old-style console dialog boxes, buttons and menus using escape sequences. – Panagiotis Kanavos Jun 30 '20 at 08:57
  • @Seabizkit that's the NUL character, just `0x00` with no special meaning. In C/C++ it's used to terminate strings. So yes, this looks like a hack to overcome a bug in the old console that nobody's using because the console is **slow** and emitting unwanted text has an impact. Better to *not* emit a trailing comma than try to erase it for every output line – Panagiotis Kanavos Jun 30 '20 at 09:04
  • I already said that's a huge problem in your approach. This is just a character that the **terminal** treats in a certain way. Other applications won't. A file just stores data, so it will just store that byte along with all others – Panagiotis Kanavos Jun 30 '20 at 09:10
  • So my understanding from the above discussion: Only text renderers need to interpret `\b`. File storage saves `"abc\bd"` as it is. Thus the text renderer will emit `"abd"` for `"abc\bd"`. Windows Console cannot interpret `\b\n`. Period. – Second Person Shooter Jun 30 '20 at 09:29

1 Answers1

6

You could use String.Join on the inner loop:

for (int i = 0; i < 5; i++)
{
  var text = String.Join(",", "Money");
  Console.Write(text);
}

Regarding your escape sequences, what \b does is down to the terminal implementation. If may opt to move back one character and delete the character, or it may just moves the cursor back one character and do nothing with what is already there.

This is the same reason that writing \0 is a bit of a back, as once again it is down to the terminal to decide how to implement the rendering of the nul character.

If you want to use escape sequences to clear the value then you can use \b to move back one character, write a space over the ,, then move back again with \b and then write the newline:

Console.Write("\b \b\n");
Sean
  • 60,939
  • 11
  • 97
  • 136
  • 1
    Did you mean `string.Join(",", "Money".Select(x => x.ToString()))`? – Sweeper Jun 30 '20 at 08:47
  • OP knows how to avoid that scenario (see the comments above). It does not answer why `\b\0\n` works, though – MakePeaceGreatAgain Jun 30 '20 at 08:48
  • @HimBromBeere the real question is why the OP is trying to delete a character instead of just *not* emitting the character. The OP probably uses the old Windows console too, which is "limited" to say the least. It's quite possible it can't handle a backspace followed by a newline, and no-one tried to use such a thing in the last 20 years, or at least, nobody reported it. The console is so slow that reducing output is important for any console application – Panagiotis Kanavos Jun 30 '20 at 08:59
  • @HimBromBeere looks like there's [a near duplicate](https://stackoverflow.com/questions/2292850/c-sharp-what-does-0-equate-to). In C/C++ the null character is the string terminator, so *maybe* this forces the console to treat `\b\0\n` as two strings. Perhaps, if the OP used `.Write('\b'); .Write(\n');` the result would be the same – Panagiotis Kanavos Jun 30 '20 at 09:07