i have a string which contains hexadecimal values i want to know how to convert that string to hexadecimal using c#
There's several ways of doing this depending on how efficient you need it to be.
Convert.ToInt32(value, fromBase) // ie Convert.ToInt32("FF", 16) == 255
That is the easy way to convert to an Int32. You can use Byte, Int16, Int64, etc. If you need to convert to an array of bytes you can chew through the string 2 characters at a time parsing them into bytes.
If you need to do this in a fast loop or with large byte arrays, I think this class is probably the fastest way to do it in purely managed code. I'm always open to suggestions for how to improve it though.
Given the following formats
10A
0x10A
0X10A
Perform the following.
public static int ParseHexadecimalInteger(string v)
{
var r = 0;
if (!string.IsNullOrEmpty(v))
{
var s = v.ToLower().Replace("0x", "");
var c = CultureInfo.CurrentCulture;
int.TryParse(s, NumberStyles.HexNumber, c, out r);
}
return r;
}
Related
Say I have a str char:
const s = '\n';
how can I convert to uint8? I believe the right value is 10.
You'll need to create a Buffer using Buffer.from(). That will give you a Buffer instance, from that you can use Buffer.readUInt8() to get the UInt8 representation of the Buffer.
function stringToUInt8 (s, offset) {
return Buffer.from(s).readUInt8(offset)
}
console.log(stringToUInt8('\n'))
I'm wanting to parse a string into a nullable int list in C#
I'm able to convert it to int list bit not a nullable one
string data = "1,2";
List<int> TagIds = data.Split(',').Select(int.Parse).ToList();
say when data will be empty i want to handle that part!
Thanks
You can use following extension method:
public static int? TryGetInt32(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}
Then it's simple:
List<int?> TagIds = data.Split(',')
.Select(s => s.TryGetInt32())
.ToList();
I use that extension method always in LINQ queries if the format can be invalid, it's better than using a local variable and int.TryParse (E. Lippert gave an example, follow link).
Apart from that it may be better to use data.Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries) instead which omits empty strings in the first place.
What's the best way (fastest performance) to convert from []int8 to string?
For []byte we could do string(byteslice), but for []int8 it gives an error:
cannot convert ba (type []int8) to type string
I got the ba from SliceScan() method of *sqlx.Rows that produces []int8 instead of string
Is this solution the fastest?
func B2S(bs []int8) string {
ba := []byte{}
for _, b := range bs {
ba = append(ba, byte(b))
}
return string(ba)
}
EDIT my bad, it's uint8 instead of int8.. so I can do string(ba) directly.
Note beforehand: The asker first stated that input slice is []int8 so that is what the answer is for. Later he realized the input is []uint8 which can be directly converted to string because byte is an alias for uint8 (and []byte => string conversion is supported by the language spec).
You can't convert slices of different types, you have to do it manually.
Question is what type of slice should we convert to? We have 2 candidates: []byte and []rune. Strings are stored as UTF-8 encoded byte sequences internally ([]byte), and a string can also be converted to a slice of runes. The language supports converting both of these types ([]byte and []rune) to string.
A rune is a unicode codepoint. And if we try to convert an int8 to a rune in a one-to-one fashion, it will fail (meaning wrong output) if the input contains characters which are encoded to multiple bytes (using UTF-8) because in this case multiple int8 values should end up in one rune.
Let's start from the string "世界" whose bytes are:
fmt.Println([]byte("世界"))
// Output: [228 184 150 231 149 140]
And its runes:
fmt.Println([]rune("世界"))
// [19990 30028]
It's only 2 runes and 6 bytes. So obviously 1-to-1 int8->rune mapping won't work, we have to go with 1-1 int8->byte mapping.
byte is alias for uint8 having range 0..255, to convert it to []int8 (having range -128..127) we have to use -256+bytevalue if the byte value is > 127 so the "世界" string in []int8 looks like this:
[-28 -72 -106 -25 -107 -116]
The backward conversion what we want is: bytevalue = 256 + int8value if the int8 is negative but we can't do this as int8 (range -128..127) and neither as byte (range 0..255) so we also have to convert it to int first (and back to byte at the end). This could look something like this:
if v < 0 {
b[i] = byte(256 + int(v))
} else {
b[i] = byte(v)
}
But actually since signed integers are represented using 2's complement, we get the same result if we simply use a byte(v) conversion (which in case of negative numbers this is equivalent to 256 + v).
Note: Since we know the length of the slice, it is much faster to allocate a slice with this length and just set its elements using indexing [] and not calling the built-in append function.
So here is the final conversion:
func B2S(bs []int8) string {
b := make([]byte, len(bs))
for i, v := range bs {
b[i] = byte(v)
}
return string(b)
}
Try it on the Go Playground.
Not entirely sure it is the fastest, but I haven't found anything better.
Change ba := []byte{} for ba := make([]byte,0, len(bs) so at the end you have:
func B2S(bs []int8) string {
ba := make([]byte,0, len(bs))
for _, b := range bs {
ba = append(ba, byte(b))
}
return string(ba)
}
This way the append function will never try to insert more data that it can fit in the slice's underlying array and you will avoid unnecessary copying to a bigger array.
What is sure from "Convert between slices of different types" is that you have to build the right slice from your original int8[].
I ended up using rune (int32 alias) (playground), assuming that the uint8 were all simple ascii character. That is obviously an over-simplification and icza's answer has more on that.
Plus the SliceScan() method ended up returning uint8[] anyway.
package main
import (
"fmt"
)
func main() {
s := []int8{'a', 'b', 'c'}
b := make([]rune, len(s))
for i, v := range s {
b[i] = rune(v)
}
fmt.Println(string(b))
}
But I didn't benchmark it against using a []byte.
Use unsafe package.
func B2S(bs []int8) string {
return strings.TrimRight(string(*(*[]byte)unsafe.Pointer(&bs)), "\x00")
}
Send again ^^
I strings in the format of name:key:dataLength:data and these strings can often be chained together. for example "aNum:n:4:9879aBool:b:1:taString:s:2:Hi" this would map to an object something like:
{
aNum: 9879,
aBool: true,
aString: "Hi"
}
I have a method for parsing a string in this format but I'm not sure whether it's use of substring is the most efficient way of pprocessing the string, is there a more efficient way of processing strings in this fashion (repeatedly chopping off the front section):
Map<string, dynamic> fromString(String s){
Map<String, dynamic> _internal = new Map();
int start = 0;
while(start < s.length){
int end;
List<String> parts = new List<String>(); //0 is name, 1 is key, 2 is data length, 3 is data
for(var i = 0; i < 4; i++){
end = i < 3 ? s.indexOf(':') : num.parse(parts[2]);
parts[i] = s.substring(start, end);
start = i < 3 ? end + 1 : end;
}
var tranType = _tranTypesByKey[parts[1]]; //this is just a map to an object which has a function that can convert the data section of the string into an object
_internal[parts[0]] = tranType._fromStr(parts[3]);
}
return _internal;
}
I would try s.split(':') and process the resulting list.
If you do a lot of such operations you should consider creating benchmarks tests, try different techniques and compare them.
If you would still need this line
s = i < 3 ? s.substring(idx + 1) : s.substring(idx);
I would avoid creating a new substring in each iteration but instead just keep track of the next position.
You have to decide how important performance is relative to readability and maintainability of the code.
That said, you should not be cutting off the head of the string repeatedly. That is guaranteed to be inefficient - it'll take time that is quadratic in the number of records in your string, just creating those tail strings.
For parsing each field, you can avoid doing substrings on the length and type fields. For the length field, you can build the number yourself:
int index = ...;
// index points to first digit of length.
int length = 0;
int charCode = source.codeUnitAt(index++);
while (charCode != CHAR_COLON) {
length = 10 * length + charCode - 0x30;
charCode = source.codeUnitAt(index++);
}
// index points to the first character of content.
Since lengths are usually small integers (less than 2<<31), this is likely to be more efficient than creating a substring and calling int.parse.
The type field is a single ASCII character, so you could use codeUnitAt to get its ASCII value instead of creating a single-character string (and then your content interpretation lookup will need to switch on character code instead of character string).
For parsing content, you could pass the source string, start index and length instead of creating a substring. Then the boolean parser can also just read the code unit instead of the singleton character string, the string parser can just make the substring, and the number parser will likely have to make a substring too and call double.parse.
It would be convenient if Dart had a double.parseSubstring(source, [int from = 0, int to]) that could parse a substring as a double without creating the substring.
I want to convert a String to an int, and all I could find is that you have to convert the String to a char array and then cast this array to an int, but my code produces strange values and I can't figure out what the problem is.
void ledDimm(String command)
{
// Get the Value xx from string LEDDimm=xx
String substring = command.substring(8, command.length());
Serial.println("SubString:");
Serial.println(substring);
Serial.println("SubString Length:");
Serial.println(substring.length());
// Create a Char Array to Store the Substring for conversion
char valueArray[substring.length() + 1];
Serial.println("sizeof ValueArray");
Serial.println(sizeof(valueArray));
// Copy the substring into the array
substring.toCharArray(valueArray, sizeof(valueArray));
Serial.println("valueArray:");
Serial.println(valueArray);
// Convert char array to an int value
int value = int(valueArray);
Serial.println("Integer Value:");
Serial.println(value);
// Write the Value to the LEDPin
analogWrite(LEDPin, value);
}
And the serial output looks like this:
Received packet of size 11
From 192.168.1.4, port 58615
Contents:
LEDDimm=100
SubString:
100
SubString Length:
3
sizeof ValueArray
4
valueArray:
100
Integer Value:
2225
I expected to get an int with the value of 100 but the actual int is 2225?! What have I done wrong here?
There is even an (undocumented) toInt() method in the String class:
int myInt = myString.toInt();
You need to use the function int value = atoi(valueArray); where valueArray is a null terminated string.
The toInt () method is very useful in this aspect, but I found that it is able to convert only strings of length five or less, especially a value less than 65535 as its the maximum value int can take. Over this value, it just gives random numbers (overflowing values). Please be aware of this when you use this method as it killed a lot of my useful time to figure this out. Hope it helps.