converting byte to string and back again - c#

I have a Byte from my database, stored as 0-254
i can convert it from a Byte to string using
byteVal.ToString() //0 return 0 20 returns 20
but to then return it back to a Byte I cannot figure out.

Similar to other number-types you need the appropriate Parse-method, in this case Byte.Parse:
Byte b = Byte.Parse("20");
If you don't know if the format is valid you can use Byte.TryParse:
Byte b;
if(!Byte.TryParse("256", out b))
Console.WriteLine("Not a valid byte");

You can use the Convert.ToByte overload which converts string to a byte

Related

How to Convert from byte? to byte[]?

I am trying to convert a byte received from a database query.
EF Core returns nullable tinyint as byte? and I need to convert it to decimal.
Is there any way to convert it OnModelCreating with model builder in the DbContext?
I am not very familiar with EF Core. So far I only managed to do this - after I already got my object in handler:
decimal? newDecimal = Convert.ToDecimal(BitConverter.ToDouble(AddByteToArray(priceByte), 0)));
private static byte[] AddByteToArray(byte? newByte)
{
if (newByte != null)
{
if(newByte == 0)
{
return Enumerable.Repeat((byte)0x0, 8).ToArray();
}
byte[] bArray = new byte[1];
// Not sure how to convert a non null and byte > 0 to byte[]?? As double requires byte[] while the tinyint return byte from the database
return bArray;
}
return null;
}
I think you are getting a little confused by the types here. The DB returns a byte? for a tinyint because a tinyint has only 8 bits of data. But otherwise it is an integer. If you want to convert it to a decimal, you would use the same mechanism as you would to convert an int or a long to a decimal: cast it. You do not want to convert a byte array to a decimal as that will try to interpret the data in the array as a binary representation of a decimal (see my last paragraph). So this code should suffice to do the conversion.
decimal? d = newByte == null ? null : (decimal)newByte;
See that such a conversion is possible here: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions
Note the remarks section here that indicates we are dealing with a binary representation of the number, where care must be taken in dealing with endianness, etc.
https://learn.microsoft.com/en-us/dotnet/api/system.bitconverter?view=net-6.0#remarks
Basically, numbers larger than a byte are technically stored as an array of bytes (since all memory is byte addressable in x86) but the interpration of those bytes into a number depends on the type of the number. For floating point numbers especially the structure of data inside the byte array is complex, broken into fields that represent the base, exponent and sign. And those are not always interpreted in a straightforward way. If you just give a byte array with 27 as the first byte, you don't know where that ends up in the several fields that make up the binary representation of a double. It may well work, but probably not.
Instead of
byte[] bArray = new byte[1];
You can use
byte[] bArray = {(byte)newByte};

A letter in a byte? C#

I have an imported C++ method that receives a byte parameter, but according to the documentation, I can send a letter to that parameter, this is the C++ and C# method:
int WINAPI Sys_InitType(HID_DEVICE device, BYTE type)
public static extern int Sys_InitType(IntPtr device, byte type);
This causes me a syntax error in C#, how do I send a letter in that parameter?
My code (A bit random):
//CRASHES
byte random = Convert.ToByte("A");
_ = RFIDReader.Sys_SetAntenna(g_hDevice, 0);
int lol = RFIDReader.Sys_InitType(g_hDevice, random);
_ = RFIDReader.Sys_SetAntenna(g_hDevice, 1);
CError.Text = lol.ToString();
Convert.ToByte(string); doesn't do what you think it does, according to the documentation
Converts the specified string representation of a number to an equivalent 8-bit unsigned integer.
This would work byte random = Conver.ToByte("52"); which will return the byte 52.
See here:
https://learn.microsoft.com/en-us/dotnet/api/system.convert.tobyte?view=net-6.0#system-convert-tobyte(system-string)
As was pointed out in the comment already, you will have to use character instead of string, so either this
byte random = Convert.ToByte('A');
or a simple cast to byte
byte random = (byte)'A'
In case it is unknown to you, which I didn't assume, a byte can only contain values of the range 0 - 255, while a character can contain everything within the specs of UTF-16.
So this will not work
byte random = Convert.ToByte('\u4542');
And result in the error:
Value was either too large or too small for an unsigned byte.
https://dotnetfiddle.net/anjxt5

C# Convert Hex string to byte

Little bit stuck on this, I have a var called PORTBhex holding a value in the range 0x00 to 0x3F which is written to an external device via USB. The problem I am having is getting the value into this bit of code:
public bool PORTBwrite()
{
Byte[] outputBuffer = new Byte[65];
outputBuffer[0] = 0;
outputBuffer[1] = 0x00; //Command tells PIC18F4550 we want to write a byte
outputBuffer[0] = 0;
//Must be set to 0
outputBuffer[2] = IO.PORTBhex;
//Hex value 0x00 - 0x3F to write to PORTB
//above line gives the error cannot implicity convert string - byte
//IO.PORTBhex is returned from the code in second snippet
if (writeRawReportToDevice(outputBuffer))
{
return true; //command completed OK
}else{
return false; //command failed .... error stuff goes here
}
}
Now the problem is the value i have is an integer that is converted to hex using:
public static string ToHex(this int value)
{
return string.Format("0x{0:X}", value);
}
The value starts off as an integer and is converted to hex however I cannot use the converted value as its of the wrong type I am getting Cannot implicitly convert type 'string' to 'byte'.
Any idea what I can do to get around this please?
Thanks
EDIT:
I think I might have poorly described what I'm trying to achieve, I have an int variable holding a value in the range 0-255 which I have to convert to Hex which must be formatted to be in the range 0x00 to 0xFF and then set outputBuffer[2] to that value to send to the microcontroller.
The integer var has some maths performed on it before it needs to be converted so i cannot solely use byte vars and has to be converted to a hex byte afterwards.
Thanks
To solution is to change PORTBhex to be of type byte and don't use that ToHex method at all:
Instead of IO.PORTBhex = ToHex(yourIntValue) use this:
IO.PORTBhex = checked((byte)yourIntValue);
It would be even better if you could make yourIntValue to be of type byte, too.
outputBuffer[2] = Convert.ToByte(IO.PORTBhex, 16);
Although personally I'd probably try to avoid strings here in the first place, and just store the byte

Convert a C char * to .Net String then to byte[]

I am having a data conversion issue that need your help.
My project is an InterOp between C and C#, all the data from C is char * type, the data itself could be binary or displayable chars, I.e. each byte is in 0x00 to 0xFF range.
I am using Data marshal::PtrToStringAnsi to convert the char* to String^ in CLI code, but I found some bytes value changed. for example C382 converted to C32C. I guess it is possibly because ANSI is only capable of converting 7-bit char, but 82 is over the range? Can anyone explain why and what is the best way?
Basically what I want to do is, I don't need any encoding conversion, I just want to convert any char * face value to a string, e.g. if char *p = "ABC" I want to String ^s="ABC" as well, if *p="C382"(represents binary value) I also want ^s="C382".
Inside my .NET code, two subclasses will take the input string that either represents binary data or real string, if it is binary it will convert "C382" to byte[]=0xC3 0x82;
When reading back the data, C382 will be fetched from database as binary data, eventually it need be converted to char* "C382".
Does anybody have similar experience how to do these in both directions? I tried many ways, they all seem to be encode ways.
The Marshal class will do this for you.
When converting from char* to byte[] you need to pass the pointer and the buffer length to the managed code. Then you can do this:
byte[] FromNativeArray(IntPtr nativeArray, int len)
{
byte[] retval = new byte[len];
Marshal.Copy(nativeArray, retval, 0, len);
return retval;
}
And in the other direction there's nothing much to do. If you have a byte[] then you can simply pass that to your DLL function that expects to receive a char*.
C++
void ReceiveBuffer(char* arr, int len);
C#
[DllImport(...)]
static extern void ReceiveBuffer(byte[] arr, int len);
....
ReceiveBuffer(arr, arr.Length);

C#: Convert a UInt16 in string format into an integer(decimal)

Here's the problem.
I ,for example,have a string "2500".Its converted from byte array into string.I have to convert it to decimal(int).
This is what I should get:
string : "2500"
byte[] : {0x25, 0x00}
UInt16 : 0x0025 //note its reversed
int : 43 //decimal of 0x0025
How do I do that?
Converting from hex string to UInt16 is UInt16.Parse(s, NumberStyles.AllowHexSpecifier).
You'll need to write some code to do the "reversal in two-digit blocks" though. If you have control over the code that generates the string from the byte array, a convenient way to do this would be to build the string in reverse, e.g. by traversing the array from length - 1 down to 0 instead of in the normal upward direction. Alternatively, assuming that you know it's exactly a 4 character string, s = s.Substring(2, 2) + s.Substring(0, 2) would do the trick.
It might be better to explicitly specify what base you want with Convert.ToUInt16.
Then, you can flip it around with IPAddress.HostToNetworkOrder (though you'll have to cast it to an int16, then cast the result back to a uint16.
there is a special class for conversion : Convert
to convert from string to uint16 use the following method: Convert.ToUInt16
for difference on int.parse and Convert.ToInt32 is explained in this page
and the msdn site for Convert.ToUInt16 here
Assuming your string is always 4 digits long.
You can get away with one string variable but I'm using multiple ones for readability.
string originalValue = "2500";
string reverseValue = originalValue.Substring(2, 2) + originalValue.Substring(0, 2);
string hexValue = Convert.ToUInt16(reverseValue, 16).ToString();
int result = Convert.ToInt32(hexValue, 10);

Categories

Resources