0

I need to covert this string strRX="16 255 128" to a string with Hex values strTX="10 FF 80.." as a string. Meaning somehow before I printing this, the string I'm going to send must change its value.

1
  • Are you looking for the code to do the conversion? What exactly is the question?
    – Tim S.
    Commented Apr 4, 2016 at 23:25

2 Answers 2

3
string strRX="16 255 128";
string strTX = string.Join(" ",strRX.Split().Select(rx => Convert.ToByte(rx).ToString("X")));
1
  • I was going to write more or less the same thing but using LINQ to turn it into a set operation instead of a loop, that's elegant. Pity the OP is unlikely to understand it... I think I will post the loop version plus some waffle about why yours is better.
    – Peter Wone
    Commented Apr 4, 2016 at 23:39
2

There are two problems to solve here.

  1. Parse a space-separated string of integers rendered in decimal format, into an array of integers.
  2. Render an array of integers as a space separated string of integers rendered in hexadecimal format.

First we split the string into an array of strings, one for each integer. Then we create somewhere to store the parsed integers, and then we process each of them preserving the order. Finally we construct the output string

string strRX = "16 255 128";
string[] ss = strRX.Split(' ');

Now we have to parse each as an integer.

int[] ii = new int[ss.Length];
for (int i = 0; i< ss.Length; i++) 
{
  ii[i] = int.Parse(ss[i]);
}

Next we render each integer as a hexadecimal string. I could create new storage for the output but I'm going to simply write over the top of the input strings. Sample output is ambiguous, but ancient convention shows bytes with leading zeroes in hex, so the format specifier is X2.

for (int i = 0; i < ss.Length; i++) 
{
  ss[i] = ii[i].ToString("X2");
}

Obviously you can do this in the same loop.

int[] ii = new int[ss.Length];
for (int i = 0; i < ss.Length; i++) 
{
  ii[i] = int.Parse(ss[i]);
  ss[i] = ii[i].ToString("X2");
}

And you don't need to keep them all in an array if you finish with them immediately, so you can collapse it further.

for (int i = 0; i < ss.Length; i++) 
{
  ss[i] = int.Parse(ss[i]).ToString("X2");
}

At this point you can put it all back together.

string strTX = string.Join(" ", ss);

And here's all of it at once.

string strRX = "16 255 128";
string[] ss = strRX.Split(' ');
for (int i = 0; i < ss.Length; i++) 
{
  ss[i] = int.Parse(ss[i]).ToString("X2");
}
string strTX = string.Join(" ", ss);

But that's clunky. You can express the whole thing far more elegantly as a set operation.

string strRX = "16 255 128";
string strTX = string.Join(" ", strRX.Split().Select(rx => int.Parse(rx).ToString("X2")));

How does that work?

  1. strRX.Split() takes an array of separators and returns an array of strings. From Cetin we learn that when the array of separators is empty the string is split on whitespace.
  2. The LINQ Select method can be applied to any IEnumerable which includes arrays.
  3. rx => int.Parse(rx).ToString("X2")) defines a lambda expression, which is a kind of inline anonymous function, which in this case the function takes a parameter rx and returns the value of int.Parse(rx).ToString("X2"). The Select method returns the array produced be calling this function on each element of the array of strings and assembling the returned values into another array.
  4. string.Join(" ", X) assembles a string from the elements of X separated by spaces.

And now, a word from our sponsor... (only kidding).

Cetin suggests in the comments that I should mention how handy Linqpad is for interactively testing and refining this sort of expression.

As it happens I too am a bit of a Linqpad fan.

4
  • Very nice lecture :) I would add, use X2 instead of X so that the output would always be padded to 2 hex digits (don't know if OP meant it). Since yours aim the beginners, I would also point to COOL LinqPad, the ultimate swiss army knife of the developer, to test these things easily. Well done. Commented Apr 5, 2016 at 5:55
  • I am afraid you need another edit :) Split() was perfectly right. In LinqPad, you can also use F1 and it takes you to help. Split(char[]) is the first constructor where the definition is Split( params char[] separator ). Having no parameters, or null, Split() Splits a string using whitespaces :) "If the separator argument is null or contains no characters, the method treats white-space characters as the delimiters. " Commented Apr 6, 2016 at 12:18
  • My first thought was that there was a no-parameters overload that had escaped my attention, so I did look at the documentation. I didn't see a no-parameter signature. However, now that you've rubbed my nose in it, I can see that a parameter array could well contain no parameters. I shall update the text.
    – Peter Wone
    Commented Apr 7, 2016 at 1:56
  • Incidentally, I checked this... using Linqpad :)
    – Peter Wone
    Commented Apr 7, 2016 at 2:14

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