Convert part of List<string> to byte[] - c#

List<string> K = new List<string>();
byte[] tmp = K[i >> 3].SelectMany(s => Encoding.Default.GetBytes(s)).ToArray();
I tying to convert, but there is an error:
The best overloaded method match for 'System.Text.Encoding.GetString(byte[])' has some invalid arguments
How correctly do this?

I'm not sure what you expect the call to K[i >> 3] to do. Your title says "convert part of a List", but what it does is simply return one string out of your List<string>.
Next, you call SelectMany() on that string. Since string is an IEnumerable<char>, the SelectMany call tries to call Encoding.Default.GetBytes() on each char in the string and return the resulting byte[] returned from each call into a combined IEnumerable<byte>. This fails, because Encoding.Default.GetBytes() expects a string parameter, not a char.
Based on your title, I expect that you expected K[i >> 3] to return an IEnumerable<string> containing a subset of your original List<string>. If it did, your code would make sense - SelectMany would pass each string in the subset to GetBytes, which would return a byte[], which would be concatenated to a larger IEnumerable<byte> containing the bytes for all the strings in the subset. But you need to fix your root cause, the subset-selection, for that to work.

Related

How to Define String Writer Length

I have a Writline C# code. However each query will bring back a diffrent length (to be populated in a excel database). I can get the length, but I am unsure how to define the n value in the Writline query below (where n will be diffrent each time, I can get the length, but how to define the writeline). Many thanks.
sw.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\......n)
I can get the length
Then you can make a format string:
var fmt = string.Concat(Enumerable.Range(0, theLength).Select(i => "{" + i + "}"));
If theLength is 3, your fmt string ends up as "{0}{1}{2}"
Other helpful factoid. The compiler takes this:
string.Format("....", a, b, c, ...);
And turns it into something like this:
var an_array = new object[]{ a, b, c, ... };
string.Format("...", an_array);
So if you already have an array there's nothing stopping you supplying it:
string.Format(fmt, your_array);
Methods that take a params arg are internally rewritten to take the N number of params as an array; you're always allowed to shortcut that and provide the array

Index of the string can be long?

I want to know whether we can give the index of the string as Long data type.
var i=long.Parse(Console.ReadLine());
var result = testString[i-1];
the second line giving me the error by saying that "The best overloaded method match for 'string.this[int]' has some invalid arguments."
No you can't use long for most collection types (you haven't specified what testString is).
One way to get around this would be to segregate the string into a multi-part / multi-dimension array then use a multiplier to get which part of the array to check.
For example:
Your index is 100,000 and you have an array of shorts (32,767 length)...
string[,] testString = new string[100, 32766]; //Replace this with your Initialisation / existing string
var arrayRank = (int)Math.Round((double) 100000 / 32767, 0);
var arrayIndex = (int)Math.Round((double)100000 % 32767, 0);
//Test this works.
//testString[arrayRank, arrayIndex] = "test"; - Test to see that the array range is assignable.
var result = testString[arrayRank, arrayIndex]; //Test value is what we expect
This may not be the most efficient way to go about things, but it is a workaround.
No, it cannot accept a long. The only overload accepts an int indexer. You would need to change your code to int.Parse() instead of long.Parse()
There is no way to pass long as an index of array, compiler doesn't allow that.
Workaround can be converting the long to int, this is called narrow conversion.
var result= testString[(int)i)];

how to copy/Convert first item in ArrayList to string in C#

I am trying to copy first item of the array list to a string variable. I did the following but it returns System.Byte[].Please help
for(i=0; i<= ArrayList.Count;i++)
{
String TEST = ArrayList[i].ToString();
}
it returns System.Byte[]
The default behavior of .ToString() just outputes the name of the type of the object. It is overridden in some types (like value types) to show some representation of the value of the object. Since ToString is not overridden for arrays you are just seeing the type name.
There are multiple ways (ASCII, UTF8, Unicode) to convert a Byte[] to a string, so you need to specify which one to use. If you want to use the default encoding for the system use
System.Text.Encoding.Default.GetString(ArrayList[i]);
It means, that the code it returning an object, which is System.Byte[] array.
ArrayList[i].ToString(); // System.Byte[]
..no matter how many times you do it. It will always return to be the same.
Use this instead
using System.Text; // <-- add this
// inside the code
for(i = 0 ; i <= ArrayList.Count ; i++ )
{
string TEST = Encoding.UTF8.GetString(ArrayList[i]);
}
..this will encode the bytes to a string representation of the data.

How to check if a byte array ends with carriage return

I want to know wether my byte array ends on carriage return and if not I want to add it.
Thats what I have tried
byte[] fileContent = File.ReadAllBytes(openFileDialog.FileName);
byte[] endCharacter = fileContent.Skip(fileContent.Length - 2).Take(2).ToArray();
if (!(endCharacter.Equals(Encoding.ASCII.GetBytes(Environment.NewLine))))
{
fileContent = fileContent.Concat(Encoding.ASCII.GetBytes(Environment.NewLine)).ToArray();
}
But I don't get it... Is this the right approach? If so, what's wrong with equals? Even if my byte array ends with {10,13}, the If statement never detects it.
In this case, Equals checks for reference equality; while endCharacter and Encoding.ASCII.GetBytes(Environment.NewLine) may have the same contents, they are not the same array, so Equals returns false.
You're interested in value equality, so you should instead individually compare the values at each position in the arrays:
newLine = Encoding.ASCII.GetBytes(Environment.NewLine);
if (endCharacter[0] != newLine[0] && endCharacter[1] != newLine[1])
{
// ...
}
In general, if you want to compare arrays for value equality, you could use something like this method, provided by Marc Gravell.
However, a much more efficient solution to your problem would be to convert the last two bytes of your file into ASCII and do a string comparison (since System.String already overloads == to check for value equality):
string endCharacter = Encoding.ASCII.GetString(fileContent, fileContent.Length - 2, 2);
if (endCharacter == Environment.NewLine)
{
// ...
}
You may also need to be careful about reading the entire file into memory if it's likely to be large. If you don't need the full contents of the file, you could do this more efficiently by just reading in the final two bytes, inspecting them, and appending directly to the file as necessary. This can be achieved by opening a System.IO.FileStream for the file (through System.IO.File.Open).
I found the solution, I must take SequenceEqual (http://www.dotnetperls.com/sequenceequal) in place of Equals. Thanks to everyone!
byte[] fileContent = File.ReadAllBytes(openFileDialog.FileName);
byte[] endCharacter = fileContent.Skip(fileContent.Length - 2).Take(2).ToArray();
if (!(endCharacter.SequenceEqual(Encoding.ASCII.GetBytes(Environment.NewLine))))
{
fileContent = fileContent.Concat(Encoding.ASCII.GetBytes(Environment.NewLine)).ToArray();
File.AppendAllText(openFileDialog.FileName, Environment.NewLine);
}

Convert String to Int (NOT PARSE)

How can i get the numeric representation of a string in C#? To be clear, I do not want the address of the pointer, I do not want to parse an int from a string, I want the numeric representation of the value of the string.
The reason I want this is because I am trying to generate a hash code based on a file path (path) and a number (line). I essentially want to do this:
String path;
int line;
public override int GetHashCode() {
return line ^ (int)path;
}
I'm up to suggestions for a better method, but because I'm overriding the Equals() method for the type I'm creating (to check that both object's path and line are the same), I need to reflect that in the override of GetHashCode.
Edit: Obviously this method is bad, that has been pointed out to me and I get that. The answer below is perfect. However, it does not entirely answer my question. I still am curious if there is a simple way to get an integer representation of the value of a string. I know that I could iterate through the string, add the binary representation of that char to a StringBuffer and convert that string to an int, but is there a more clean way?
Edit 2: I'm aware that this is a strange and very limited question. Converting in this method limits the size of the string to 2 chars (2 16 bit char = 1 32 bit int), but it was the concept I was getting at, and not the practicality. Essentially, the method works, regardless of how obscure and useless it may be.
If all you want is a HashCode, why not get the hashcode of the string too? Every object in .net has a GetHashCode() function:
public override int GetHashCode() {
return line ^ path.GetHashCode();
}
For the purposes of GetHashCode, you should absolutely call GetHashCode. However, to answer the question as asked (after clarification in comments) here are two options, returning BigInteger (as otherwise you'd only get two characters in before probably overflowing):
static BigInteger ConvertToBigInteger(string input)
{
byte[] bytes = Encoding.BigEndianUnicode.GetBytes(input);
// BigInteger constructor expects a little-endian byte array
Array.Reverse(bytes);
return new BigInteger(bytes);
}
static BigInteger ConvertToBigInteger(string input)
{
BigInteger sum = 0;
foreach (char c in input)
{
sum = (sum << 16) + (int) c;
}
return sum;
}
(These two approaches give the same result; the first is more efficient, but the second is probably easier to understand.)

Categories