Convert a ASCII string to Hex string - c#

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.

string strRX="16 255 128";
string strTX = string.Join(" ",strRX.Split().Select(rx => Convert.ToByte(rx).ToString("X")));

There are two problems to solve here.
Parse a space-separated string of integers rendered in decimal format, into an array of integers.
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?
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.
The LINQ Select method can be applied to any IEnumerable which includes arrays.
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.
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.

Related

Error Message when converting an array of strings from a text file to an array of doubles

I just have a quick (I think) question regarding a program I'm working on in C#. I have a text file with a long list of numbers, like this:
41.673993158 0.000000000 258.436256
41.673992499 -0.000001364 258.462068
41.673991841 -0.000002700 258.487880
And I need to create an array that contains each number separately as a double(or float). i.e.
Array[0] = 41.673993158
Array[1] = 0.000000000 ...etc.]
Right now, I have the numbers in an array, but they are all strings. I have the following code:
string text = System.IO.File.ReadAllText("/Applications/Unity/Projects/Underwater/SampleFile.txt");
if (text != null)
{
string[] strings = text.Split (' ');
System.Console.WriteLine("Contents of SampleFile = ");
for (int i = 0; i < strings.Length; i++)
{
Console.WriteLine (strings[i]);
}
}
This code works perfect. It outputs each number on a separate line in the console, which leads me to believe that each number has it's own place in the array. However, they are all still strings, so when I try to convert them to doubles using this code:
double[] nums = new double[strings.Length];
for (int i = 0; i < strings.Length; i++)
{
nums[i] = Convert.ToDouble(strings[i]);
}
I get thrown an exception error, and can't figure out why. Here's the error message:
System.FormatException has been thrown.
Unknown Char
Details:
double.Parse (s="258.436256\r\n41.673992499", provider={en-CA})
System.Convert.ToDouble (value="258.436256\r\n41.673992499")
I can't move on in my program until I have an array of doubles, so any help is greatly appreciated!
You can see from your exception message that it's trying to parse two numbers at once that are separated by a carriage return.
You're splitting by space, but not by line. Writing this to the console would look correct, however.
Change your split to include both space and CRLF:
text.Split(new[] {" ", "\r\n"}, StringSplitOptions.RemoveEmptyEntries);
You could even combine with some LINQ to parse and then create the array - this is a far terser solution:
var nums = text
.Split(new[] {" ", "\r\n"}, StringSplitOptions.RemoveEmptyEntries)
.Select(double.Parse)
.ToArray();
See this fiddle for a working demo.

Extracting an integer from a string

I have a personal ID and an Industry ID that I would like to compare with each other, but the industry number has zeros and an alphabet character in front. and some numbers are longer than others.
ex.
Personal Number | Industry Number
123 | J000123
1234 | L001234
12345 | M012345
I know how to solve the problem if it was ONLY zeros. Character throws me around, how would I achieve this?
i assume PersonalNumber is a Int and IndustryNumber is has type String
bool Result = int.Parse(string.Concat(PersonalNumber.Skip(1))) == IndustryNumber;
For the updated question (i.e. industry number starts with arbitrary letter followed by a number padded by zeros) it could be
// Remove 1st letter, than remove zeros
String number = IndustryNumber.Substring(1).TrimStart('0');
if (number.Equals(personalNumber)) {
...
}
Use RegEx:
var numb = int.Parse(RegEx.Match(industryNumber, #"\d+^").Value);
//Then compare the two ints
Create a function for given code below
string a = "str123";
string b = string.Empty;
int val;
for (int i=0; i< a.Length; i++)
{
if (Char.IsDigit(a[i]))
b += a[i];
}
if (b.Length>0)
val = int.Parse(b);
then call getInt(mystring)==int
by Dominik answer
Regex.Replace("J0123", "([A-z]*)", "");
You can use a Regex to remove the first part of the Industry number:
Regex.Replace("J0123", "J0*", "");
results in "123"
UPDATE, to account for all letters use this regex:
Regex.Replace("J0123", "[A-Z]0*", "");
You need to use substring() on the Industry Number and Convert after:
I assume you use an array of string with 2 dimensions. string[,] myarray.
for (int i = 0; i<myarray.GetLengh(0);i++)
{
//get personnal number as integer, this is simple
int personnal = Convert.ToInt32(myarray[i][0]);
//get industry number as integer, this is the difficult part
string strIndustry = myarray[i][1];
strIndustry = strIndustry.SubString(0,1);//remove the first char
int industry = Convert.ToInt32(strindustry);//I assume that you only have numbers after the letter if not you may need to test it with tryParse...
//then you can now compare integers
if(personnal==industry)
{
//your code to execute if true
}
else{//...}
}
Assuming you have two arrays for PersonalId and IndustryID.Result is another array to which will hold the result.
for(int i=0; i< PersonalID.Count i++)
{
if(IndustryID[i].Contains(PersonalID[i]))
{
Result[i]=true;
}
else
Result[i]=False;
}

How to split a string based on every third character regardless of what the character is in c# [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
.NET String.Format() to add commas in thousands place for a number
I am trying to add commas to a number for the presentation layer and need to cast and then split the number on every third character in order to join on a ','.
So if i have a string like this
546546555
desired output:
546,546,555
Other times, the number could be longer or shorter:
254654
desired output:
254,654
Is it possible to split in this manner then join with a comma?
tahnks!
EDIT:
Hi Everyone,
Thanks very much for your help.
To add to this post I also found a way to do this in SQL:
SUBSTRING(CONVERT(varchar, CAST(NumItems AS money), 1), 0, LEN(CONVERT(varchar, CAST(NumDocs AS money), 1)) - 2) as [NumDocs]
Rather than splitting the string manually, you should convert it to a number (or leave it as a number), and call the ToString method with the appropriate formatting:
Example
int value = 546546555;
string displayValue = value.ToString("#,#");
See this MSDN page for different format values:
C - Currency format
D - Decimal format
E - Scientific format
F - Fixed point format
G - General format
N - Number format
P - Percent format
R - Round trip format
X - Hexadecimal format
You should do this by converting your string to an integer, using Parse or ideally TryParse and use string formatting to display it:
var str = "546546555";
var formatted = String.Empty;
int value = 0;
if(int.TryParse(str,out value))
{
formatted = value.ToString("#,#");
}
Live example: http://rextester.com/FHO11833
Assuming you aren't only trying to output numbers, here's a quick function that I believe would do what you are after:
string splitter(string tosplit, int num, string splitstring)
{
string output = "";
for (int i = 0; i < tosplit.Length; i += num)
if (i + num < tosplit.Length)
output += tosplit.Substring(i, num) + ",";
else
output += tosplit.Substring(i);
return output;
}
Here, the output of splitter("546546555", 3, ",") would be 546,546,555
This would not be ideal for numbers though, as the other answers would cover this case perfectly.
Not very good code, but it works.
public static string GetString(string val, int number)
{
List<string> res = new List<string>();
res.Add("");
int counter = 0, i = 0;
while (i < val.Length)
{
while (res[counter].Length < number && i < val.Length)
{
res[counter] += val[i];
i++;
}
res.Add("");
counter++;
}
return string.Join(",", res.Where(r => !string.IsNullOrEmpty(r)));
}
val - your input string
number - number of characters you want to split, equals to 3 in your case
Gene S and Dan seem to have the answer IMHO. The nice thing about using the built in formatting is that you can write localizable code. For example, the "," is the numeric group separator in the US, but the "." is used in Spain.
var val = 12345678;
CultureInfo c = CultureInfo.CurrentCulture;
Application.CurrentCulture = new CultureInfo("EN-us");
var s = String.Format("{0:#,#}", val);
Application.CurrentCulture = new CultureInfo("ES-es");
var i = String.Format("{0:#,#}", val);
Application.CurrentCulture = c;

How can I make nested string splits?

I have what seemed at first to be a trivial problem but turned out to become something I can't figure out how to easily solve. I need to be able to store lists of items in a string. Then those items in turn can be a list, or some other value that may contain my separator character. I have two different methods that unpack the two different cases but I realized I need to encode the contained value from any separator characters used with string.Split.
To illustrate the problem:
string[] nested = { "mary;john;carl", "dog;cat;fish", "plainValue" }
string list = string.Join(";", nested);
string[] unnested = list.Split(';'); // EEK! returns 7 items, expected 3!
This would produce a list "mary;john;carl;dog;cat;fish;plainValue", a value I can't split to get the three original nested strings from. Indeed, instead of the three original strings, I'd get 7 strings on split and this approach thus doesn't work at all.
What I want is to allow the values in my string to be encoded so I can unpack/split the contents just the way before I packed/join them. I assume I might need to go away from string.Split and string.Join and that is perfectly fine. I might just have overlooked some useful class or method.
How can I allow any string values to be packed / unpacked into lists?
I prefer neat, simple solutions over bulky if possible.
For the curious mind, I am making extensions for PlayerPrefs in Unity3D, and I can only work with ints, floats and strings. Thus I chose strings to be my data carrier. This is why I am making this nested list of strings.
try:
const char joinChar = '╗'; // make char const
string[] nested = { "mary;john;carl", "dog;cat;fish", "plainValue" };
string list = string.Join(Convert.ToString(joinChar), nested);
string[] unnested = list.Split(joinChar); // eureka returns 3!
using an ascii character outside the normal 'set' allows you to join and split without ruining your logic that is separated on the ; char.
Encode your strings with base64 encoding before joining.
The expected items are 7 because you're splitting with a ; char. I would suggest to change your code to:
string[] nested = { "mary;john;carl", "dog;cat;fish", "plainValue" }
string list = string.Join("#" nested);
string[] unnested = list.Split('#'); // 3 strings again
Have you considered using a different separator, eg "|"?
This way the joined string will be "mary;john;carl|dog;cat;fish|plainValue" and when you call list.split("|"); it will return the three original strings
Use some other value than semicolon (;) for joining. For example - you can use comma (,) and you will get "mary;john;carl,dog;cat;fish,plainValue". When you again split it based on (,) as a separator, you should get back your original string value.
I came up with a solution of my own as well.
I could encode the length of an item, followed with the contents of an item. It would not use string.Split and string.Join at all, but it would solve my problem. The content would be untouched, and any content that need encoding could in turn use this encoding in its content space.
To illustrate the format (constant length header):
< content length > < raw content >
To illustrate the format (variable length header):
< content length > < header stop character > < raw content >
In the former, a fixed length of characters are used to describe the length of the contents. This could be plain text, hexadecimal, base64 or some other encoding.
Example with 4 hexadecimals (ffff/65535 max length):
0005Hello0005World
In the latter example, we can reduce this to:
5:Hello5:World
Then I could look for the first occurance of : and parse the length first, to extract the substring that follows. After that is the next item of the list.
A nested example could look like:
e:5:Hello5:Worlda:2:Hi4:John
(List - 14 charactes including headers)
Hello (5 characters)
World (5 characters)
(List - 10 characters including headers)
Hi (2 characters)
John (4 characters)
A drawback is that it explicitly requires the length of all items, even if no "shared separator" character wouldn't been present (this solution use no separators if using fixed length header).
Maby not as nice as you wanted. But here goes :)
static void Main(string[] args)
{
string[] str = new string[] {"From;niklas;to;lasse", "another;day;at;work;", "Bobo;wants;candy"};
string compiledString = GetAsString(str);
string[] backAgain = BackToStringArray(compiledString);
}
public static string GetAsString(string[] strings)
{
string returnString = string.Empty;
using (MemoryStream ms = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(ms))
{
writer.Write(strings.Length);
for (int i = 0; i < strings.Length; ++i)
{
writer.Write(strings[i]);
}
}
ms.Flush();
byte[] array = ms.ToArray();
returnString = Encoding.UTF8.GetString(array);
}
return returnString;
}
public static string[] BackToStringArray(string encodedString)
{
string[] returnStrings = new string[0];
byte[] toBytes = Encoding.UTF8.GetBytes(encodedString);
using (MemoryStream stream = new MemoryStream(toBytes))
{
using (BinaryReader reader = new BinaryReader(stream))
{
int numStrings = reader.ReadInt32();
returnStrings = new string[numStrings];
for (int i = 0; i < numStrings; ++i)
{
returnStrings[i] = reader.ReadString();
}
}
}
return returnStrings;
}

String operations in C#

Suppose I have a string "011100011".
Now I need to find another string by adding the adjacent digits of this string, like the output string should be "123210122".
How do I split each characters in the string and manipulate them?
The method that I thought was to convert the string to integer using Parsing and splitting each character using modulus or something and performing operations on them.
But can you suggest some simpler methods?
Here's a solution which uses some LINQ plus dahlbyk's idea:
string input = "011100011";
// add a 0 at the start and end to make the loop simpler
input = "0" + input + "0";
var integers = (from c in input.ToCharArray() select (int)(c-'0'));
string output = "";
for (int i = 0; i < input.Length-2; i++)
{
output += integers.Skip(i).Take(3).Sum();
}
// output is now "123210122"
Please note:
the code is not optimized. E.g. you might want to use a StringBuilder in the for loop.
What should happen if you have a '9' in the input string -> this might result in two digits in the output string.
Try converting the string to a character array and then subtract '0' from the char values to retrieve an integer value.
string input = "011100011";
int current;
for (int i = 0; i < input.Length; i ++)
{
current = int.Parse(input[i]);
// do something with current...
}

Categories

Resources