0

I'm writing a tiny hex viewer for my own needs. Stuck in a situation where the standard Label control won't show up an unprintable characters in string:

public string ToASCIIstring(int numColumns)
{
    string ret = String.Empty;
    int stringBegin = 0;

    for (int i = 0; i < Data.Length; i++)
    {
        int colNum = i % numColumns;

        if ((colNum + 1 == numColumns) || (i == Data.Length -1 ))
        {
            ret += Encoding.ASCII.GetString(Data, stringBegin, colNum);
            stringBegin = i + 1;
            ret += "\n";
        }
    }

    return ret;
}

This method returns the correct ASCII string, but after assigning it to the Label.Text property it becomes just an Empty string and nothing is displayed.

Any help on that would be lovely

P.S. I know the code is awful, but it's never gonna see the production, it's just my own analysis tool

Xaruth
  • 4,034
  • 3
  • 19
  • 26
schikin
  • 21
  • 4
  • Well, unprintable characters are... unprintable. Things like ASCII 7 really have no glyph to represent them. Try displaying a '.' instead. – Kris Vandermotten Oct 21 '13 at 14:48
  • Please try Encoding.Unicode.GetString... . Also try to set some hardcoded text to tghe label, maybe it's just in the background – VladL Oct 21 '13 at 14:49
  • If you want to display hex then you have to actually convert the bytes to hex. Use BitConverter.ToString(). You'll find sample code that does both in [this answer](http://stackoverflow.com/a/2426258/17034). – Hans Passant Oct 21 '13 at 14:54
  • looks like you know what that **ASCII string** is, could you try showing that **ASCII string** here or at least reveal its **ASCII code** to let us try? – King King Oct 21 '13 at 18:38
  • @KrisVandermotten Well yeah, I could manually check for the unprintable characters and replace them with some symbol. That was my first idea on that. The thing is it's not how the things should work probably - I can see the string in debugger as well as print it to the console (it beeps and all that but still prints it) - but I can't assign it to the Label. That's pretty much weird - it's a CLR string basically, so Label should be able to print it regardless of what's inside – schikin Oct 22 '13 at 06:45
  • @HansPassant it's not meant to get the HEX string basically - it's for getting its ASCII representation. To get the HEX I use the String.Format("{0:X2}"); – schikin Oct 22 '13 at 06:47
  • @KingKing Any data containing a mix of binary data and null-terminated ASCII strings will do. I don't want to reveal the original data as it's basically a reverse engineering project and after half a year of debugging the handmade cryptography out of it - I'd not want the developers to know that I've got to the plaintext messages :) – schikin Oct 22 '13 at 06:51
  • What do you mean by "I can't assign it to the Label"? The function you showed us isn't assigning its result to anything. Show us the code where you make the assignment, and tell us precisely what goes wrong. – Kris Vandermotten Oct 22 '13 at 07:19
  • @KrisVandermotten private void lstMsg_SelectedIndexChanged(object sender, EventArgs e) { VisualizeMessage msg = (VisualizeMessage)lstMsg.SelectedItem; lblMsg.Text = msg.ToHEXString(8); lblASCII.Text = msg.ToASCIIstring(8); } That's the assignment code this.lblASCII = new System.Windows.Forms.Label(); That's Label instantiation The string returned by the VisualizeMessage.ToASCIIstring(8) is ok - I can see it as well as print to the console. After assigning it to lblASCII.Text the latter is Empty. – schikin Oct 22 '13 at 07:27
  • Sure, but "tell us precisely what goes wrong". Have you set a breakpoint at `lblASCII.Text = msg.ToASCIIstring(8)`? Step over that line and inspect `lblASCII.Text` and `lblASCII.Text.Length` before and after. What happens? – Kris Vandermotten Oct 22 '13 at 07:30
  • @KrisVandermotten ofc I did. The string returned is fine. lblASCII has it's standard text before the assignment ("label2") but gets cleared out after it – schikin Oct 22 '13 at 07:32

1 Answers1

0

I cannot reproduce you problem.

I created a new Windows Forms application using .NET Framework 4.5, and I put one Label on the form. I then have the following code:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    string s = ((char)7).ToString();

    this.label1.Text = s;

    Debug.Assert(this.label1.Text == s);
}

As expected, it runs just fine. Using the default font, this displays a thin bullet.

My guess is that something else is going wrong that has nothing to do with non-printable ASCII characters.

UPDATE: However, the Windows API's behind the label use null-terminated strings, meaning that a zero byte will be interpreted as the end of the string. So the following program fails:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    var bytes = new byte[] { 7, 0, 0x6c, 0 };

    string s = Encoding.ASCII.GetString(bytes);

    this.label1.Text = s;

    Debug.Assert(this.label1.Text == s);
}

After the assignment, the Label.Text property contains a string of length 1, only containing the character with ASCII code 7.

But this works:

    var bytes = new byte[] { 7, 0, 0x6c, 0 };

    string s = Encoding.ASCII.GetString(bytes).Replace((char)0, '.');

    this.label1.Text = s;

    Debug.Assert(this.label1.Text == s);
Kris Vandermotten
  • 10,111
  • 38
  • 49
  • True, (char)7 works fine for me as well. Now try doing this: byte[] arr = new byte[] { 7, 0, 0x6c, 0 }; //for example this.label1.Text = Encoding.ASCII.GetString(arr,0,arr.Length); Probably, it's due to the \0 characters... – schikin Oct 22 '13 at 07:59
  • Yeah, I got the same results. Thank you – schikin Oct 22 '13 at 08:13