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.
Related
I have a string,
string Var="11001100"
I want to convert it into a byte array.
bArray[0]=0x00;
bArray[1]=0x00;
bArray[2]=0x01;
bArray[3]=0x01;
bArray[4]=0x00;
bArray[5]=0x00;
bArray[6]=0x01;
bArray[7]=0x01;
Can anybody guide me in this? I tried the following code, but I get the data in ASCII. I do not want that.
bArray = Encoding.Default.GetBytes(var);
I suggest using Linq:
using System.Linq;
...
string Var = "11001100";
byte[] bArray = Var
.Select(item => (byte) (item == '0' ? 1 : 0))
.ToArray();
Test:
Console.WriteLine(string.Join(Environment.NewLine, bArray
.Select((value, index) => $"bArray[{index}]=0x{value:X2};")));
Outcome:
bArray[0]=0x00;
bArray[1]=0x00;
bArray[2]=0x01;
bArray[3]=0x01;
bArray[4]=0x00;
bArray[5]=0x00;
bArray[6]=0x01;
bArray[7]=0x01;
but I get the data in ASCII. I do not want that.
Then you need the string representation of the chars. You get it using the ToString method. This would be the old scool way simply using a reversed for-loop:
string Var="11001100";
byte [] bArray = new byte[Var.Length];
int countForward = 0;
for (int i = Var.Length-1; i >= 0 ; i--)
{
bArray[countForward] = Convert.ToByte(Var[i].ToString());
countForward++;
}
This is my solution for your question:
string value = "11001100";
int numberOfBits = value.Length;
var valueAsByteArray = new byte[numberOfBits];
for (int i = 0; i < numberOfBits; i++)
{
bytes[i] = ((byte)(value[i] - 0x30)) == 0 ? (byte)1 : (byte)0;
}
Edit: Forgot the inversion.
I am trying to work through a scenario I haven't seen before and am struggling to come up with an algorithm to implement this properly. Part of my problem is a hazy recollection of the proper terminology. I believe what I am needing is a variation of the standard "combination" problem, but I could well be off there.
The Scenario
Given an example string "100" (let's call it x), produce all combinations of x that swap out one of those 0 (zero) characters for a o (lower-case o). So, for the simple example of "100", I would expect this output:
"100"
"10o"
"1o0"
"1oo"
This would need to support varying length strings with varying numbers of 0 characters, but assume there would never be more than 5 instances of 0.
I have this very simple algorithm that works for my sample of "100" but falls apart for anything longer/more complicated:
public IEnumerable<string> Combinations(string input)
{
char[] buffer = new char[input.Length];
for(int i = 0; i != buffer.Length; ++i)
{
buffer[i] = input[i];
}
//return the original input
yield return new string(buffer);
//look for 0's and replace them
for(int i = 0; i != buffer.Length; ++i)
{
if (input[i] == '0')
{
buffer[i] = 'o';
yield return new string(buffer);
buffer[i] = '0';
}
}
//handle the replace-all scenario
yield return input.Replace("0", "o");
}
I have a nagging feeling that recursion could be my friend here, but I am struggling to figure out how to incorporate the conditional logic I need here.
Your guess was correct; recursion is your friend for this challenge. Here is a simple solution:
public static IEnumerable<string> Combinations(string input)
{
int firstZero = input.IndexOf('0'); // Get index of first '0'
if (firstZero == -1) // Base case: no further combinations
return new string[] { input };
string prefix = input.Substring(0, firstZero); // Substring preceding '0'
string suffix = input.Substring(firstZero + 1); // Substring succeeding '0'
// e.g. Suppose input was "fr0d00"
// Prefix is "fr"; suffix is "d00"
// Recursion: Generate all combinations of suffix
// e.g. "d00", "d0o", "do0", "doo"
var recursiveCombinations = Combinations(suffix);
// Return sequence in which each string is a concatenation of the
// prefix, either '0' or 'o', and one of the recursively-found suffixes
return
from chr in "0o" // char sequence equivalent to: new [] { '0', 'o' }
from recSuffix in recursiveCombinations
select prefix + chr + recSuffix;
}
This works for me:
public IEnumerable<string> Combinations(string input)
{
var head = input[0] == '0' //Do I have a `0`?
? new [] { "0", "o" } //If so output both `"0"` & `"o"`
: new [] { input[0].ToString() }; //Otherwise output the current character
var tails = input.Length > 1 //Is there any more string?
? Combinations(input.Substring(1)) //Yes, recursively compute
: new[] { "" }; //Otherwise, output empty string
//Now, join it up and return
return
from h in head
from t in tails
select h + t;
}
You don't need recursion here, you can enumerate your patterns and treat them as binary numbers. For example, if you have three zeros in your string, you get:
0 000 ....0..0....0...
1 001 ....0..0....o...
2 010 ....0..o....0...
3 011 ....0..o....o...
4 100 ....o..0....0...
5 101 ....o..0....o...
6 110 ....o..o....0...
7 111 ....o..o....o...
You can implement that with bitwise operators or by treating the chars that you want to replace like an odometer.
Below is an implementation in C. I'm not familiar with C# and from the other answers I see that C# already has suitable standard classes to implement what you want. (Although I'm surprised that so many peolpe propose recursion here.)
So this is more an explanation or illustration of my comment to the question than an implementation advice for your problem.
int binrep(char str[])
{
int zero[40]; // indices of zeros
int nzero = 0; // number of zeros in string
int ncombo = 1; // number of result strings
int i, j;
for (i = 0; str[i]; i++) {
if (str[i] == '0') {
zero[nzero++] = i;
ncombo <<= 1;
}
}
for (i = 0; i < ncombo; i++) {
for (j = 0; j < nzero; j++) {
str[zero[j]] = ((i >> j) & 1) ? 'o' : '0';
}
printf("%s\n", str); // should yield here
}
return ncombo;
}
Here's a solution using recursion, and your buffer array:
private static void Main(string[] args)
{
var a = Combinations("100");
var b = Combinations("10000");
}
public static IEnumerable<string> Combinations(string input)
{
var combinations = new List<string>();
combinations.Add(input);
for (int i = 0; i < input.Length; i++)
{
char[] buffer= input.ToArray();
if (buffer[i] == '0')
{
buffer[i] = 'o';
combinations.Add(new string(buffer));
combinations = combinations.Concat(Combinations(new string(buffer))).ToList();
}
}
return combinations.Distinct();
}
The method adds the raw input as the first result. After that, we replace in a loop the 0s we see as a o and call our method back with that new input, which will cover the case of multiple 0s.
Finally, we end up with a couple duplicates, so we use Distinct.
I know that the earlier answers are better. But I don't want my code to go to waste. :)
My approach for this combinatorics problem would be to take advantage of how binary numbers work. My algorithm would be as follows:
List<string> ZeroCombiner(string str)
{
// Get number of zeros.
var n = str.Count(c => c == '0');
var limit = (int)Math.Pow(2, n);
// Create strings of '0' and 'o' based on binary numbers from 0 to 2^n.
var binaryStrings = new List<string>();
for (int i = 0; i < limit; ++i )
{
binaryStrings.Add(Binary(i, n + 1));
}
// Replace each zero with respect to each binary string.
var result = new List<string>();
foreach (var binaryString in binaryStrings)
{
var zeroCounter = 0;
var combinedString = string.Empty;
for (int i = 0; i < str.Length; ++i )
{
if (str[i] == '0')
{
combinedString += binaryString[zeroCounter];
++zeroCounter;
}
else
combinedString += str[i];
}
result.Add(combinedString);
}
return result;
}
string Binary(int i, int n)
{
string result = string.Empty;
while (n != 0)
{
result = result + (i % 2 == 0 ? '0' : 'o');
i = i / 2;
--n;
}
return result;
}
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);
I am new programmer in C# and I wanna know if there is a direct way to convert from StringBuilder to int. I have the following code. On the last line of the code I get an error.
StringBuilder newnum = new StringBuilder();
for (int i = x.Length - 1; i >= 0; i--)
{
newnum.Append(x[i]);
}
int x = Convert.ToInt32(newnum);
You can solve this problem by simply converting the StringBuilder to String before passing it to the Convert.ToInt32 method;
You have three different options for converting textual data to an Integer:
1:
int i = int.Parse(sb.ToString());
2:
int i = Convert.ToInt32(sb.ToString());
3:
int i;
int.TryParse(sb.ToString(), out i);
int x = Convert.ToInt32(newnum.ToString());
int x = int.parse(newnum.tostring());
I'm trying to convert a String of hex to ASCII, using this:
public void ConvertHex(String hexString)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hexString.Length; i += 2)
{
String hs = hexString.Substring(i, i + 2);
System.Convert.ToChar(System.Convert.ToUInt32(hexString.Substring(0, 2), 16)).ToString();
}
String ascii = sb.ToString();
MessageBox.Show(ascii);
}
but I get an out or bounds exception, I'm sure its a glaring error but other code I have tried does not work either. What am I doing wrong?
This code will convert the hex string into ASCII, you can copy paste this into a class and use it without instancing
public static string ConvertHex(String hexString)
{
try
{
string ascii = string.Empty;
for (int i = 0; i < hexString.Length; i += 2)
{
String hs = string.Empty;
hs = hexString.Substring(i,2);
uint decval = System.Convert.ToUInt32(hs, 16);
char character = System.Convert.ToChar(decval);
ascii += character;
}
return ascii;
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
return string.Empty;
}
Notes
2 = the no. of hexString chars used to represent an ASCII character.
System.Convert.ToUInt32(hs, 16) = "convert the base 16 hex substrings to an unsigned 32 bit int"
There are four three problems here:
Since you're incrementing i by 2 on each iteration, you need to terminate at hexString.Length - 1. This doesn't actually matter; incrementing by two after the final iteration will bring the counter above the checked length regardless.
You're taking the wrong number of characters from hexString.
hs is never used.
You're not appending anything to sb.
Try this:
for (int i = 0; i < hexString.Length; i += 2)
{
string hs = hexString.Substring(i, 2);
sb.Append(Convert.ToChar(Convert.ToUInt32(hs, 16)));
}
Note that there's no need to qualify the types with their namespace, System (assuming you've referenced it at the top of the file with a using statement).
String hs = hexString.Substring(i, i + 2);
System.Convert.ToChar(System.Convert.ToUInt32(hexString.Substring(0, 2), 16)).ToString();
Do you notice you're never using hs ??
And that you're converting the first 2 chars over and over?
Since you are incrementing your index by 2, you need to stop your loop one-before-the-end of the length of the string. Otherwise your last iteration of the loop will try to read characters past the end of the string.
for (int i = 0; i < hexString.Length - 1, i += 2)