1

Today I was presented with a very nasty problem and I do not quite know where to ask this but hope here is ok.

So I have the following string: "\0" (at least that's how it looks in visual studio). If you open the same file in notepad++ it looks like this: "\0SOH". so yes, I have reached a point where I need to check a string which has non printable characters. The problem is the string I am comparing against are hardcoded and would come to look like this:

switch (s)
{
    case "\0\0":
        Console.WriteLine("Crypto method 00");
        break;
    case "\0":
        Console.WriteLine("Crypto method 01");
        break;
    case "\0":
        Console.WriteLine("Crypto method 02");
        break;
    case "\0":
        Console.WriteLine("Crypto method 03");
        break;
    default:
        Console.WriteLine(s);
        break;
}

complete example code can be found on pastbin for the next month

But the code is not important, this, the display of this code, it is horrible and that's the problem. I cannot possibly commit something like this because no one will know what is happening.

Of course I could add comments so my co-workers will know what's going on but to me that does not seem like the proper solution. so my question what is the proper solution to create understandable code in this situation? Do I ask my co-workers to rewrite their code to make it work with byte arrays? Do I simply keep it this way?

A way to resolve this in code would be: ASCIIEncoding.Default.GetString(new byte[]{0, 1}); but this 'hack' does not really make it more understandable.

To clarify, I am not looking for a code fix, I can think of several (such as mentioned above) I am looking for advice on how to handle this or perhaps a way to make sure the (for example Visual studio) editor will distinguish between them.


Some extra context
A piece of old code handling the TCP connection receives the data (like it should) and then returns a string, it uses ASCII encode to create a string from the received byte[].

We have now gotten to a point where higher on we need to set/read a few status bytes which, because of the way we get messages from the TCP layer result in unreadable strings.

It is possible to rewrite the TCP to only send byte[] arrays but this is going to take up more time than anyone is willing to put in.

3

You could do the comparison of the bytes by storing the strings as constants, with decent names. So case "\0\0": would become case STATUS_CRYPTO_1: which helps remove the 'magic number' aspect of your switch statement.

But the correct solution here is to add some comments. That's what comments were designed for, that's their intended purpose. Some documentation at the top of your function is probably the best place to say what the byte array is that you're comparing against, and why.

| improve this answer | |
  • +1 Regardless of whether or not the strings were readable, I'd likely flag the fact that they weren't in constants anyways in a code review. Then tack comments onto the constant declarations. – J Trana Jun 2 '15 at 1:14
8

As can already be seen in the question, using such non-printable characters directly in a string-literal makes the code essentially unreadable. At first glance, you would say that the presented code should fail to compile because there are multiple identical case labels.

Most languages (and that includes C#) support escape sequences to deal with troublesome characters like line-breaks, quotes and non-printable characters. Just like that you would use \n to represent a line-break in a string, you can use \x01 to represent the character U+0001 (ASCII SOH)in a string.
This is very commonly used when the string type is (mis-)used to represent byte data. As an example, your code would become:

switch (s)
{
    case "\x00\x00":
        Console.WriteLine("Crypto method 00");
        break;
    case "\x00\x01":
        Console.WriteLine("Crypto method 01");
        break;
    case "\x00\x02":
        Console.WriteLine("Crypto method 02");
        break;
    case "\x00\x03":
        Console.WriteLine("Crypto method 03");
        break;
    default:
        Console.WriteLine(s);
        break;
}
| improve this answer | |
  • is that what he was asking - how to represent a byte as a string character? I assumes the repeated \0s were just placeholders for the actual bytes! – gbjbaanb Jun 1 '15 at 16:15
  • @gbjbaanb: That is what I took to be the question. The leading zeros in the printed strings made me suspect that the "\0" strings were not placeholders but the actual byte content. Which doesn't invalidate your answer in any way, especially the first paragraph. – Bart van Ingen Schenau Jun 2 '15 at 6:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.