I have written this piece of code:
int i = 0;
br.BaseStream.Position = i;
armorvalues[i] = br.ReadBytes(0x000E91D4);
string[] outbyte= new string[0x000E91D4];
for (int j=0; j < 0x000E91D4; j++)
{
outbyte[j] = Convert.ToString(String.Format("{0:X2}", armorvalues[0][j]));
}
Now since this is an array and I want to some algorithmic operations on the whole data, I need to convert it into a string. i need to append it in a single string. What should I do?
Not sure why you want to do so, maybe if you explain better your need then it'll be good. But for your question:
You can use string.Join:
var strValue = string.Join(" ", outbyte);
And instead of doing it after the look you can also:
var strValue = string.Join(" ", armorvalues[0].Select(item => String.Format("{0:X2}", item)));
Take a look at the StringBuilder class
StringBuilder sb = new StringBuilder(0x000E91D4*2); // length * 2 since every byte is going to be represented by 2 chars
for (int j=0; j < 0x000E91D4; j++)
{
sb.Append(Convert.ToString(String.Format("{0:X2}", armorvalues[0][j])));
}
string yourString = sb.ToString();
Edit:
I was not aware of that string.Join overload that takes an IEnumerable, that it more elegant, go with Gilad Green's solution or if you don't want the values be separated by an empty space (" ") just do
string output = string.Concat(armorvalues[0].Select(item => String.Format("{0:X2}", item)));
Related
G'day,
I have a char array that varies in size based on the length of some data. The array will never be larger than 24 though. It may however, be less than 24. As a result of this I need to "pad left" with 0's, as in add more elements to the left of the array to make it 24. I have below some code that does this, just wondering if there is a faster way or more efficient way to do so. Thanks!
Note: I don't think this is a duplicate as I am working with char[]'s not strings.
char[] dataLen = Convert.ToString(data.Length, 2).ToCharArray();
int j = 0;
char[] tmp = new char[24];
for (int i = 0; i < 24; i++)
{
if (i < (24 - dataLen.Length))
tmp[i] = '0';
else
tmp[i] = dataLen[j++];
}
dataLen = tmp;
Why don't you simply use String.PadLeft?
char[] data = "abcdefgh".ToCharArray(); // sample data
data = new string(data).PadLeft(24, '0').ToCharArray();
That should be efficient and is also very readable.
how about :
string z24 = "000000000000000000000";
tmp = z24.Take(24 - dataLen.Length).Union(dataLen).ToArray();
I would simply use a string for all operations, and use PadLeft to do the padding.
string input = new string(data);
string result = input.PadLeft(24, '0');
Then convert it to a char[] if you really need to:
char[] chars = result.ToCharArray();
(Also, your Convert.ToString(data.Length, 2) doesn't return their string representation, new string(data) does)
ListBox box = GetListBox(); //placeholder for the sample
string s = "123456776543219898989";
char[] c = s.ToCharArray();
for(int i=0;i<c.Length;i+=7)
{
box.Items.Add(new string(c, i, 7));
}
This is fast way to separate text.
you can do an easy for loop
ListBox box = null;//set it yourself
for(int i = 0; i < s.Length; i+= 7)
{
box.Items.Add(s.SubString(i, Math.Min(s.Length - i, 7));
}
Break the string into a character array, and use that to create your items. This string constructor overload will help:
http://msdn.microsoft.com/en-us/library/ms131424.aspx
This code is just a sample. What you actually need will depend on how you want to handle the situation where the number of characters in the original string is not evenly divisible by 7.
ListBox box = GetListBox(); //placeholder for the sample
string s = "123456776543219898989";
char[] c = s.ToCharArray();
for(int i=0;i<c.Length;i+=7)
{
box.Items.Add(new string(c, i, 7));
}
I could also do this directly on the string, instead of creating the array, but this should be much faster than calling .SubString() repeatedly.
var str = "123456776543219898989";
int count = 0;
var parts = str.GroupBy(_ => count++ / 7)
.Select(x => string.Concat(x))
.ToArray();
listBox1.Items.AddRange(parts);
Hi I'm developing an client application in C# and the server is written in c++
the server uses:
inline void StrToInts(int *pInts, int Num, const char *pStr)
{
int Index = 0;
while(Num)
{
char aBuf[4] = {0,0,0,0};
for(int c = 0; c < 4 && pStr[Index]; c++, Index++)
aBuf[c] = pStr[Index];
*pInts = ((aBuf[0]+128)<<24)|((aBuf[1]+128)<<16)|((aBuf[2]+128)<<8)|(aBuf[3]+128);
pInts++;
Num--;
}
// null terminate
pInts[-1] &= 0xffffff00;
}
to convert an string to int[]
in my c# client i recieve:
int[4] { -14240, -12938, -16988, -8832 }
How do I convert the array back to an string?
I don't want to use unsafe code (e.g. pointers)
Any of my tries resulted in unreadable strings.
EDIT:
Here is one of my approch:
private string IntsToString(int[] ints)
{
StringBuilder s = new StringBuilder();
for (int i = 0; i < ints.Length; i++)
{
byte[] bytes = BitConverter.GetBytes(ints[i]);
for (int j = 0; j < bytes.Length; j++)
s.Append((char)(bytes[j] & 0x7F));
}
return s.ToString();
}
I know I need to take care of endianess but as the server is running on my local machine and the server too, I assume that this is not a problem.
My other try was to use an struct with explicit layout and same FieldOffset for integer and chars but it doesn't work, either.
Maybe try something like (using LINQ):
int[] fromServer = { -14240, -12938, -16988, -8832, };
string reconstructedStr = new string(fromServer.SelectMany(BitConverter.GetBytes).Select(b => (char)(b - 128)).ToArray());
Untested, but there's something to start from. Don't know if the subtraction of 128 is correct.
You can create a comma separated string this way:
string str = String.Join(", ", intArray.Select(x => x.ToString()).ToArray());
var ints = new[] {-14240, -12938, -16988, -8832};
var result = string.Join("-", ints.Select(i => BitConverter.ToString(BitConverter.GetBytes(i))));
Console.WriteLine(result); //60-C8-FF-FF-76-CD-FF-FF-A4-BD-FF-FF-80-DD-FF-FF
BitConverter.ToString can be replaced by something else here, depending on how you will parse string later.
i can't find any mistakes in my code.
here i'm trying to pick all numbers from the string:
(just to simplify the example,, i want to pick numbers that will satisfy some condition)
i use Queue cause i don't want to deal with array's indexes.
Console.Write("enter string: ");
string s = Console.ReadLine();
char[] array = s.ToCharArray();
Queue<char> q = new Queue<char>();
for (int i = 0; i < array.Length; i++)
{
q.Enqueue(array[i]);
}
char[] new_array = new char[q.Count];
for (int i = 0; i < q.Count; i++)
{
new_array[i] = q.Dequeue();
}
Console.WriteLine(new String(new_array));
Input string: 123456
And the output is a little weird:
123
another input: 123
output: 12
of course i made some mistake) but everything seems to be OK
Thank YOU in advance
The problem is the second loop:
for (int i = 0; i < q.Count; i++)
{
new_array[i] = q.Dequeue();
}
As q.Count decrements on every loop iteration, and i increases on every interation, you get only half of the elements.
try something like:
for (int i = 0; q.Count > 0; i++)
{
new_array[i] = q.Dequeue();
}
also consider: Queue.toArray
I would suggest using List<char> instead of Queue<char> and char[]. There's nothing here that particularly needs a queue, and it would avoid the problem that Rudolf pointed out, and a List is much easier to work with than an array. You can also use foreach instead of a for loop, and avoid the intermediate step.
Console.Write("enter string: ");
string s = Console.ReadLine();
List<char> new_array = new List<char>();
foreach(char c in s.ToCharArray())
{
new_array.Add(c);
}
Console.WriteLine(new String(new_array.ToArray()));
As the reason for your error is already stated,you can replace your two loops with just two statements
//A version of Queue constructor accepts IEnumerable object.
//you can directly pass the string to the queue constructor.
Queue<char> Que = new Queue<char>("123456");
//Copies the array and the position is preserved
var new_arr= Que.ToArray();
According to MSDN:
Removes and returns the object at the beginning of the Queue.
As you use Dequeue(), the q.Count value changes in each iteration.
So rather than using q.Count in this loop;
for (int i = 0; i < q.Count; i++)
use
int queueSize = q.Count;
for (int i = 0; i < queueSize; i++)
This will keep your looping limit as a constant number rather than calculating it in each iteration to find a different value because of using Dequeue().
If you take a look at the plastic in your wallet the 16 digit credit card number is broken into 4 groups of 4. Im trying to do the same thing,
Currently I have a string that has 16 digits but is formed as 1 single number. How can I add a " " after the 4th 8th & 12th number?
Any tips would be really helpful.
Thanks
var number = 1234567890123456;
number.ToString( "0000-0000-0000-0000" );
Try something similar to this answer, using a NumberFormatInfo:
NumberFormatInfo format = new NumberFormatInfo();
format.NumberGroupSeparator = " ";
format.NumberGroupSizes = new[] { 4 };
format.NumberDecimalDigits = 0;
Use as:
long number = 7314787188619939;
string formatted = number.ToString("n", format);
Console.WriteLine(formatted);
Or, if you're dealing with a string, you may choose can use a regex for a quick string manipulation. This will be easy to adapt to other characters:
string str = "7314787188619939";
str = Regex.Replace(str, "(?!^).{4}", " $0" ,RegexOptions.RightToLeft);
string number = "1234567890ABCDEF";
int counter = 0;
var result = number
.GroupBy(_ => counter++ / 4)
.Select(g => new String(g.ToArray()));
There are many answers. Given a string s=1234567890123456 the easiest might be to create a StringBuilder and append it. Untested code example below.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.Length; i += 4)
{
sb.append(s.Substring(i, 4)); // Append these 4
if (i != s.Length - 4)
sb.append(" "); // append a space for all but the last group
}
Console.WriteLine(sb.ToString());
You may try something like this, an extension method
public static IEnumerable<String> SplitToParts(this String forSplit, Int32 splitLength)
{
for (var i = 0; i < forSplit.Length; i += splitLength)
yield return forSplit.Substring(i, Math.Min(splitLength, forSplit.Length - i));
}
string s ="1234123412341234";
s.SplitToParts(4) should do the trick
Hope this works !
Or if working with MD5 hashes, you could use an implementation like so...
public string exHashMd5(string data)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(data));
byte[] result = md5.Hash;
StringBuilder str = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
str.Append(result[i].ToString("X2"));
}
/// The implementation like so. (Below)
NumberFormatInfo format = new NumberFormatInfo();
format.NumberGroupSeparator = " ";
format.NumberGroupSizes = new[] { 8 };
format.NumberDecimalDigits = 0;
string rstr = str.ToString();
rstr = Regex.Replace(rstr, "(?!^).{8}", " $0", RegexOptions.RightToLeft);
return rstr.ToString();
/// At the end you get yourself a nice 4 way split.
/// Test it out. have a go with chucking it into a
/// MessageBox.Show(exHashMd5("yourstring"));
}
/// Could even go one further and add
string hashtext;
string newline = Enviroment.Newline;
hashtext = exHashMd5("yourtext");
/// Then you do a simple command.
MessageBox.Show(hashtext + newline + hashtext);
/// Nice four way again. complex but yet made simple.
To work out what you need it to do, use maths. seriously, its mathematical. divide the amount of characters, till you are able to get a sum that equals four. for example, 32 / 8 = 4. then this will give you the four way split you need. basic maths. basic. basic. basic.