I want to input a series of Hex numbers into a textBox and when the user hits a button separate each byte with a comma. AAFFBCEE becomes AA,FF,BC,EE (no comma on last byte). how can I convert a string value to this format?
string temp = "aaff4455";
string temp2 = "";
int size = temp.Length;
for (int i = 0; i < size; i += 2)
{
temp2 += temp.Substring(i, 2);
if ((i+2) < size)
temp2 += ",";
}
Why not use a 1-liner?
var str = "AABBCCDD";
var result = "";
str.ToCharArray()
.Select((c, i) => new { i, c })
.ToList()
.ForEach(c => result += (c.i > 0 && c.i % 2 == 0) ? "," + c.c : c.c.ToString());
(I'm still learning Linq so be nice!)
Related
I want to split a string into smaller parts, not exceeding a string length of 20 characters.
The current code is able to split an input string into an array of strings of length 20. However, this could cut a word.
The current code is:
string[] Array;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
if (i % 20 == 0 && i != 0) {
sb.Append('~');
}
sb.Append(input[i]);
}
Array = sb.ToString().Split('~');
For an input of this: Hello. This is a string. Goodbye., the output would be ['Hello. This is a str', 'ing. Goodbye.'].
However, I don’t want the string to be cut if it’s a word. That word should move to the next string in the array. How can I get the following output instead?
['Hello. This is a', 'string. Goodbye.']
First split your sentence on word-boundary:
var words = myString.Split();
Now concatenate words as long as not more than 20 characters are within your current line:
var lines = new List<string> { words[0] };
var lineNum = 0;
for(int i = 1; i < words.Length; i++)
{
if(lines[lineNum].Length + words[i].Length + 1 <= 20)
lines[lineNum] += " " + words[i];
else
{
lines.Add(words[i]);
lineNum++;
}
}
Here is a fiddle for testing: https://dotnetfiddle.net/s0LrFC
Could be more elegant but this will split the string to lines of a maximum number of characters. The words will be kept together unless they exceed the given length.
public static string[] SplitString(string input, int lineLen)
{
StringBuilder sb = new StringBuilder();
string[] words = input.Split(' ');
string line = string.Empty;
string sp = string.Empty;
foreach (string w in words)
{
string word = w;
while (word != string.Empty)
{
if (line == string.Empty)
{
while (word.Length >= lineLen)
{
sb.Append(word.Substring(0, lineLen) + "~");
word = word.Substring(lineLen);
}
if (word != string.Empty)
line = word;
word = string.Empty;
sp = " ";
}
else if (line.Length + word.Length <= lineLen)
{
line += sp + word;
sp = " ";
word = string.Empty;
}
else
{
sb.Append(line + "~");
line = string.Empty;
sp = string.Empty;
}
}
}
if (line != string.Empty)
sb.Append(line);
return sb.ToString().Split('~');
}
To test:
string[] lines = SplitString("This is a test of the string splitter KGKGKJGKGHKJHJKJKHGJHGhghsjagsjasgajsgjahs yes!", 20);
foreach (string line in lines)
{
Console.WriteLine(line);
}
Output:
This is a test of the
string splitter
KGKGKJGKGHKJHJKJKHGJ
HGhghsjagsjasgajsgja
hs yes!
I believe it's faster to split it only at places where it needs to be, instead of every word. With lines.SelectMany(x => Split(x, 80) can be used with multiline texts:
private static IEnumerable<string> Split(string text, int maxLength)
{
var i = 0;
while (i + maxLength < text.Length)
{
var partIndex = text.LastIndexOf(' ', i + maxLength, maxLength);
if (partIndex == -1)
partIndex = i + maxLength;
yield return text[i..partIndex];
i = partIndex + 1;
}
yield return text[i..];
}
I am trying to write a code to merge two string based on index of character.For e.g-If we have two string "abc" and "defg",I want a string output1(merging all even character of both strings)="adcf" and another string output2="beg" (remaining all words).
What I tried-
class Program
{
static void Main(string[] args)
{
string a= "First";
string b= "MiddleName";
string newstring = "";
string newstring1 = "";
int length = b.Length;
for (int l = 0; l < length; l=l+1)
{
if(l%2==0)
{
newstring = newstring + a[l].ToString() + b[l].ToString();
}
if (l % 2 == 1)
{
newstring1 = newstring1 + a[l].ToString() + b[l].ToString();
}
}
Console.ReadLine();
}
}
But then in this case it will give outside the bound array exception.Any better way to do this?
Thanks
I suggest extracting a method where you should solve the generalized problem of merging two strings taking each step characters from them starting from offset:
private static String Merge(String left, String right, int step, int offset) {
StringBuilder sb = new StringBuilder();
if (null == left)
left = ""; // or throw exception
if (null == right)
right = ""; // or throw exception
for (int i = offset; i < Math.Max(left.Length, right.Length); i += step) {
//DONE: do not forget to check if you can get a character
if (i < left.Length)
sb.Append(left[i]);
//DONE: do not forget to check if you can get a character
if (i < right.Length)
sb.Append(right[i]);
}
return sb.ToString();
}
And so you can put it
String a = "abc";
String b = "defg";
// adcf
String output1 = Merge(a, b, 2, 0);
// beg
String output2 = Merge(a, b, 2, 1);
it happens because B has longer words than A. So when its iteration is bigger than A' length, it will cause an error.
so you need to check whether A has that much word, before adding it
IF B' length always greater than A, then you can use bellow code
class Program
{
static void Main(string[] args)
{
string a= "First";
string b= "MiddleName";
string newstring = "";
string newstring1 = "";
int length = b.Length;
for (int l = 0; l < length; l=l+1)
{
if(l%2==0)
{
if(a.Length > l)
{newstring += a[l].ToString();}
newstring += b[l].ToString();
}
if (l % 2 == 1)
{
if(a.Length > l)
{newstring1 += a[l].ToString();}
newstring1 += b[l].ToString();
}
}
Console.ReadLine();
}
}
for (int l = 0; l < b.length && l < a.length; l++)
{
if(l%2==0)
{
newstring += a[l]+ b[l];
}
if (l % 2 == 1)
{
newstring1 += a[l] + b[l];
}
}
I have a string in c#. I want to split that string into 2 words string sets like:
string str = "Split handles splitting upon string and character delimiters."
Output should be:
1: "Split handles"
2: "splitting upon"
3: "string and"
4: "character delimiters."
What should be the best method to do this?
Here is what i have tried yet:
private List<string> Spilt(string text)
{
List<string> bunch = new List<string>();
int block = 15;
string[] words = text.Split(' ');
int length = words.Length;
int remain = 0;
while(remain < length)
{
bunch.Add(string.Join(" ", words.Take(block)));
remain += block;
}
return bunch;
}
The simplest approach would be to split at each space, and then "re-join" the pairs back, like this:
var pairs = str.Split(' ')
.Select((s,i) => new {s, i})
.GroupBy(n => n.i / 2)
.Select(g => string.Join(" ", g.Select(p=>p.s)))
.ToList();
Demo on ideone.
Try this
string str = "Split handles splitting upon string and character delimiters.";
var strnew = str.Split(' ');
var strRes = string.Empty;
int j = 1;
for (int i = 0; i < strnew.Length; i=i+2)
{
strRes += j.ToString()+": " + #"""" + strnew[i] + " " + strnew[i+1] + #"""" +"\n" ;
j++;
}
Console.Write(strRes);
// print strRes
I have an array of numbers jumbled up from 0-9.
How do I sort them in ascending order?
Array.Sort doesn't work for me. Is there another way to do it?
Thanks in advance.
EDIT:
Array.Sort gives me this error.
Argument 1: cannot convert from 'string' to 'System.Array'
Right now it gives me this output:
0) VersionInfo.xml
2) luizafroes_singapore2951478702.xml
3) virua837890738.xml
4) darkwizar9102314425644.xml
5) snarterz_584609551.xml
6) alysiayeo594136055.xml
1) z-a-n-n2306499277.xml
7) zhangliyi_memories932668799030.xml
8) andy_tan911368887723.xml
9) config.xml
k are the numbers from 0-9
string[] valnames = rk2.GetValueNames();
foreach (string k in valnames)
{
if (k == "MRUListEx")
{
continue;
}
Byte[] byteValue = (Byte[])rk2.GetValue(k);
UnicodeEncoding unicode = new UnicodeEncoding();
string val = unicode.GetString(byteValue);
Array.Sort(k); //Error here
richTextBoxRecentDoc.AppendText("\n" + k + ") " + val + "\n");
}
Your problem is that k is not an Array but a string !
I have the feeling that this is what you want to do :
string[] valnames = rk2.GetValueNames();
valnames = valnames.OrderBy (s => int.Parse(s)).ToArray();
for (int i= 0 ; i < balnames.Lenght ; i++)
{
k = valenames[i];
if (k == "MRUListEx")
{
continue;
}
Byte[] byteValue = (Byte[])rk2.GetValue(k);
UnicodeEncoding unicode = new UnicodeEncoding();
string val = unicode.GetString(byteValue);
richTextBoxRecentDoc.AppendText("\n" + i + ") " + val + "\n");
}
Are you sure you have an array in integers or have you stored an array of System.Object, in which case you'll have problems with leading space.
You are trying to sort a String. That's not possible.
This code will give you the output you want:
string[] valnames = rk2.GetValueNames();
for (int i = valnames.Length - 1; i >= 0; i--)
{
string k = valnames[i];
if (k == "MRUListEx")
continue;
Byte[] byteValue = (Byte[])rk2.GetValue(k);
UnicodeEncoding unicode = new UnicodeEncoding();
string val = unicode.GetString(byteValue);
richTextBoxRecentDoc.AppendText("\n" + k + ") " + val + "\n");
}
How do you convert a string such as "01110100011001010111001101110100" to a byte array then used File.WriteAllBytes such that the exact binary string is the binary of the file. In this case it would be the the text "test".
In case you don't have this LINQ fetish, so common lately, you can try the normal way
string input ....
int numOfBytes = input.Length / 8;
byte[] bytes = new byte[numOfBytes];
for(int i = 0; i < numOfBytes; ++i)
{
bytes[i] = Convert.ToByte(input.Substring(8 * i, 8), 2);
}
File.WriteAllBytes(fileName, bytes);
LINQ is great but there must be some limits.
You could start by splitting the string into a sequence of 8-character strings, then convert those strings to bytes, and eventually write the bytes to a file
string input = "01110100011001010111001101110100";
var bytesAsStrings =
input.Select((c, i) => new { Char = c, Index = i })
.GroupBy(x => x.Index / 8)
.Select(g => new string(g.Select(x => x.Char).ToArray()));
byte[] bytes = bytesAsStrings.Select(s => Convert.ToByte(s, 2)).ToArray();
File.WriteAllBytes(fileName, bytes);
EDIT: here's another way to split the string into 8-character chunks, perhaps a bit simpler :
int nBytes = (int)Math.Ceiling(input.Length / 8m);
var bytesAsStrings =
Enumerable.Range(0, nBytes)
.Select(i => input.Substring(8 * i, Math.Min(8, input.Length - 8 * i)));
If you know that the length of the string is a multiple of 8, you can make it even simpler :
int nBytes = input.Length / 8;
var bytesAsStrings =
Enumerable.Range(0, nBytes)
.Select(i => input.Substring(8 * i, 8));
A bit late, but here's my 2 cents:
var binaryStr = "01110100011001010111001101110100";
var byteArray = Enumerable.Range(0, int.MaxValue/8)
.Select(i => i*8)
.TakeWhile(i => i < binaryStr.Length)
.Select(i => binaryStr.Substring(i, 8))
.Select(s => Convert.ToByte(s, 2))
.ToArray();
File.WriteAllBytes("C:\temp\test.txt", byteArray);
Actually the answer by #Maciej is not correct. As #Phate01 noticed the numOfBytes is correct only for input length which is a power of 8. The second thing is that the byte array should be populated from n to 0 index not the opposite way. Here's the code example:
var bits = "000011110000001000";
var numOfBytes = (int)Math.Ceiling(bits.Length / 8m);
var bytes = new byte[numOfBytes];
var chunkSize = 8;
for (int i = 1; i <= numOfBytes; i++)
{
var startIndex = bits.Length - 8 * i;
if (startIndex < 0)
{
chunkSize = 8 + startIndex;
startIndex = 0;
}
bytes[numOfBytes - i] = Convert.ToByte(bits.Substring(startIndex, chunkSize), 2);
}
This can be improved to get rid of the if statetment but in this form it's more understandable.
The other answers have you covered, but just for fun I wrote the opposite. Going from the string to the ascii binary representation:
private static string StringToAsciiBin(string s)
{
string output = "";
foreach (char c in s.ToCharArray())
{
for (int i = 128; i >= 1; i /=2)
{
if (((int)c & i) > 0)
{
output += "1";
}
else
{
output += "0";
}
}
}
return output;
}