I have two strings
string A = "1.0.0.0";
string B = "1.0.0.1";
I need to evaluate somehow that B is greater than A (version wise) either converting those two strings to integers or decimals or something.
I tried the following
Decimal S = Convert.ToDecimal(A);
int S = Convert.ToInt32(A);
but keep getting the following error, "Input string was not in a correct format."
Any help will be appreciated.
See the Version Class.
You're able to do something like this:
Version a = new Version("1.0.0.0");
Version b = new Version("1.0.0.1");
if (b>a) //evaluates to true
blah blah blah
I haven't personally tested this exact scenario, but the Version class allows you to use comparison operators like I've shown here.
If your string has at most 4 numeric parts (separated by .), you can use the Version class to get a strongly typed entity that corresponds to these strings. Version implements the different comparison operators (==, >, < etc...) in the expected manner, so you can find out which is greater:
var a = new Version(A);
var b = new Version(B);
if(a > b)
// a is larger
else if (a < b)
// b is larger
else
// they are identical
If there are more than 4 parts, you will need to split each string to its numeric components, convert each one to a numeric equivalent and compare the two resulting collections.
Something like:
var aParts = A.Split('.');
var bParts = B.Split('.');
// assumes the string have the same number of parts
for(int i = 0; i < aParts.Length; i++)
{
var currA = int.Parse(aParts[i]);
var currB = int.Parse(bParts[i]);
if(currA == currB)
continue;
if(currA > currB)
// A is greater than B
else
// B is greater than A
}
You can take a look at System.Version class.
If the strings are in this format or can be converted to a version.
Version have comparers
If you want to compare version strings in .NET, then you can use the Version class.
Version version = new Version("1.0.0.0");
Version otherVersion = new Version(""1.0.0.1");
The class provides operators to check if a version is greater or lesser than another.
Split on the ".". Then convert each part to an int. Starting from the left: if A's fragment is lower, then report that A is first. If B's fragment is lower, then report that B is first. Otherwise, move to the next fragment. If you're at the last fragment already, report that they are equal.
If your strings have at most four parts (like version numbers), then as others suggested it's easier to use the System.Version class.
Instead of using VersionClass a fast approach would be something like this.
string A = "1.0.0.0";
string B = "1.0.0.1";
int versionA = Convert.ToInt32(A.Replace(".", string.Empty));
int versionB = Convert.ToInt32(B.Replace(".", string.Empty));
if (b>a)
//something will happen here
Replace changes the first string to the second one in this case string.Empty equals to "".
Related
following problem in C# (working in VS Community 2015):
First off, i fairly new to C#, so excuse me if that question would be an easy fix.
I have a contact sensor giving me a string of numbers (length measurement). I read them with the SystemPort Methods and cut them down to the numbers that i need with substring (as the beginning of the string, the "SR00002" is useless to me).
In the end i end up with a string like : "000.3422" or "012.2345". Now i want to convert that string to one solid int-variable that i can work with, meaning subtract values from and such.
Bsp: I want to calculate 012.234 - 000.3422 (or , instead of . but i could change that beforehand)
I already tried Parse and ConvertToInt (while iterating through the string) but the endresult is always a string.
string b = serialPort2.ReadLine();
string[] b1 = Regex.Split(b, "SR,00,002,");
string b2 = b1[1].Substring(1);
foreach (char c in b2)
{
Convert.ToInt32(c);
}
textBox2.Text = b2 + b2.GetType();
I know that when b2 will be int it can not be printed in the Textbox but ill take care of that later.
When everything is converted accordingly, ill outsource the conversion to its own method =)
The GetType is just for testing and as said shows only System.String (which i dont want). Help would be much appreaciated. I also browsed the searchfunction and google but couldnt find anything of help. I wish any possible helpers a nice day, mfg Chris.
use the int.Parse
int.Parse("123")
You need to assign the converted values to a new variable or array that takes int or other numeric values that you want.
int[] numbers = new int[b1.length];
for(int i = 0; i < b2.length; i++)
{
numbers[i] = Convert.ToInt32(b2[i]);
}
I created 3 strings:
string a = "abcdgfg";
string b = "agbfcd";
string c = "axcvn";
I want to create the following check but i can't find out how:
Need to check if in string a and string b there are the same latters (never mind the order or if a latter shown more than once, just need to check if the same latter appears on both strings).
Then i need to do the same check for string a and string c.
as you can see: string a and string b have the same latters, stringa a and string c don't.
after i do the checking i simply print a massage if the strings have the same latter or not
Can anyone show me how to do the cheking?
Edit:
after check "a" and "c", it o should print the first latter that came up and not match between "a" and "c"
Thanks
I would suggest to use a HashSet<T> and it's SetEquals:
var aSet = new HashSet<char>(a);
var bSet = new HashSet<char>(b);
bool abSame = aSet.SetEquals(b);
Edit
after check "a" and "c", it o should print the first latter that came
up and not match between "a" and "c"
Then you can use HashSet.SymmetricExceptWith:
if (!abSame)
{
aSet.SymmetricExceptWith(bSet);
Console.WriteLine("First letter that is either in a and not in b or in b and not in a: " + aSet.First());
}
By the way, this can also replace the SetEquals check:
aSet.SymmetricExceptWith(bSet); // removes all characters which are in both
if (aSet.Any()) // missing charaters in one of both strings
{
Console.WriteLine("First letter that is either in a and not in b or in b and not in a: " + aSet.First());
}
The original answer using Except + Any had a subtle bug. Checking the length is not sufficient if there are duplicates. So you need to check from both directions or use Distinct first. Both approaches are inefficient compared to the HashSet.SetEquals-method which is a O(n) operation.
bool abSame = !a.Except(b).Any() && !b.Except(a).Any();
private bool HaveSameLetters(string a, string b)
{
return a.All(x => b.Contains(x)) && b.All(x => a.Contains(x));
}
Need to check if in string a and string b there are the same latters (never mind the order or if a latter shown more than once, just need to check if the same latter appears on both strings).
You can do it like this:
bool same = a.Distinct().OrderBy(c => c)
.SequenceEqual(b.Distinct().OrderBy(c => c));
This simply sorts the characters of two strings and checks if the two ordered sequence are equal. You can use the same method for a and c.
How can i make bitwise operations on strings at c#
example
string sr1="0101110";
string sr2="1101110";
sr1 & sr2="0101110";
or
sr1 | sr2="1101110";
How can i make such comparison ?
Notice string lengths are fixed 1440 characters
Here my dirty solution
private string compareBitWiseAnd(string sr1, string sr2)
{
char[] crArray1 = sr1.ToCharArray();
char[] crArray2 = sr2.ToCharArray();
StringBuilder srResult = new StringBuilder();
for (int i = 0; i < crArray1.Length; i++)
{
if (crArray1[i] == crArray2[i])
{
srResult.Append(crArray1[i]);
}
else
{
srResult.Append('0');
}
}
return srResult.ToString();
}
private string compareBitWiseOr(string sr1, string sr2)
{
char[] crArray1 = sr1.ToCharArray();
char[] crArray2 = sr2.ToCharArray();
StringBuilder srResult = new StringBuilder();
for (int i = 0; i < crArray1.Length; i++)
{
if (crArray1[i] == '1' || crArray2[i] == '1')
{
srResult.Append("1");
}
else
{
srResult.Append('0');
}
}
return srResult.ToString();
}
Convert to actual bits first, and then do the bitwise comparison.
int num1 = Convert.ToInt32(sr1, 2);
int num2 = Convert.ToInt32(sr2, 2);
int result = num1 & num2;
Use this if you want to get a binary string from the result.
BigInteger is the type you are looking for. It also have BitwiseOr.
If you really need to stick with strings it is not very hard to compute bitwise operations on character-by-character basis... but I'd avoid doing it if possible.
And here is a question on how to construct BigInteger from string of any base - BigInteger Parse Octal String?
var bitString = "10101";
BigInteger value = bitString.Aggregate(new BigInteger(), (b, c) => b * 2 + c - '0');
You have to convert the string to numbers first, you can use "Convert.ToInt32(String, Int32)", the second parameter lets you specify the base:
string sr1 = "0101110";
string sr2 = "1101110";
int one = Convert.ToInt32(sr1, 2);
int two = Convert.ToInt32(sr2, 2);
int result = one & two;
hope it helps.
You can't do bitwise operations on a string in the way you intend. There are interesting things you can do with bitwise operations on strings with other goals, like changing their case, but I think this is what you want:
// Convert the string to an integer
int foo = Convert.ToInt32(sr1, 2);
int bar = Convert.ToInt32(sr2, 2);
// Perform binary styff
int result = foo & bar;
// Convert back to a string, if you want
string resultStr = result.ToString();
I like Alexei's BigInteger solution, but it does require .NET 4.0 minimum. If for some reason you can't use that, then another option is to use the BitArray class, which has been available since .NET 1.1. Unfortunately, there is no method built-in to BitArray to parse a binary string, so you have to do that manually, similar to Alexei's solution.
Another option is a class I wrote called BoolArray which does a lot of the same things as BitArray, but does have a method to parse binary strings - use the static BoolArray.FromBinaryString method:
BoolArray bin = BoolArray.FromBinaryString("1001011000111010101"); // etc
Here is the BoolArray source code. Note, however, that it isn't quite complete, and isn't fully tested either, but I'm not immediately aware of any bugs.
EDIT: I noticed after pasting the original link that the code used a function provided in a different class of my "Utils" library, and wouldn't have compiled directly. I've updated the link to provide this class in the code as well... hopefully that was the only case, but if not let me know and I can fix.
Is there a way a comparison in a string value can return a Boolean value. Example.
If (5 > 5000) would obviously return a false value. But what i wanted to do is have the "5 > 5000" return a false value.
Example.
string com = "5 > 10";
so is there a way to make this com variable return a false value as if it was a comparison between integers.
No built-in way but NCalc can help here
NCalc.Expression expr = new NCalc.Expression("5>10");
bool b = (bool)expr.Evaluate();
You can even use parameters
NCalc.Expression expr = new NCalc.Expression("a<b");
expr.EvaluateParameter += (name, args) =>
{
if (name == "a") args.Result = 5;
if (name == "b") args.Result = 10;
};
bool b = (bool)expr.Evaluate();
There is no built-in way to do this.
Although there are a couple of ways to approach this, one is to simply parse the text yourself. I did this in the code presented in the article A C# Expression Evaluator. You might want to review that code.
No, this can't be done directly.
You should write your own class or extend the String class. For handling a string such as "5 < 10", you need your own method.
You should search the string for signs that indicate comparison, such as "<", "==" etc, then split it and perform the comparison.
Basically: doing it yourself is the only way, but you can try to do it in an elegant way.
Short answer: no.
Long answer: feel free to parse the string yourself, looking for > < and =. Split by whitespace, parse ints then evaluate. It might get harder if you want it to work with parentheses as well...
Not directly, per se (short of the unsafe Javascript eval-execute-my-data hack) but you can try parsing it yourself, depending on how complicated of an expression you want to accept. For example, this should work with the string you have:
var arr = com.Split('>').Select(x=>int.Parse(x.Trim())).ToArray();
return arr[0] > arr[1];
You can also use regular expressions to get more complicated (untested, but it ought to work):
var r = new Regex(#"(\d+)\b*(<|>|=|<=|>=)\b*(\d+)")
var match = r.Match(com);
if(match.Success)
{
var a = int.Parse(match.Captures[0]);
var b = int.Parse(match.Captures[2]);
switch(match.Captures[1])
{
case "<":
return a < b;
case "=":
return a = b;
case ">":
return a > b;
case "<=":
return a <= b;
case "<=":
return a >= b;
}
}
//uh-oh
throw new ArgumentException("com");
Consider using FLEE:
Flee is an expression parser and evaluator for the .NET framework. It allows you to compute the value of string expressions such as sqrt(a^2 + b^2) at runtime. It uses a custom compiler, strongly-typed expression language, and lightweight codegen to compile expressions directly to IL. This means that expression evaluation is extremely fast and efficient. Try out the demo, which lets you generate images based on expressions, and see for yourself.
With FLEE you can easily accomplish this using something like:
var con = new ExpressionContext();
const string com = #"5 > 5000";
var comparison = con.CompileDynamic(com);
var result = comparison.Evaluate();
MessageBox.Show(result.ToString());
HTH...
I have string qty__c which may or may not have a decimal point
The code below gives me a System.ArgumentOutOfRangeException: Length cannot be less than zero.
qty__c = qty__c.Substring(0, qty__c.IndexOf("."));
How do i cater to if there is no "."?
Thanks
The simplest way is just to test it separately:
int dotIndex = quantity.IndexOf('.');
if (dotIndex != -1)
{
quantity = quantity.Substring(0, dotIndex);
}
There are alternatives though... for example if you really wanted to do it in a single statement, you could either use a conditional operator above, or:
quantity = quantity.Split('.')[0];
or slightly more efficiently:
// C# 4 version
quantity = quantity.Split(new[] {'.'}, 2)[0];
// Pre-C# 4 version
quantity = quantity.Split(new char[] {'.'}, 2)[0];
(The second form effectively stops splitting after finding the first dot.)
Another option would be to use regular expressions.
On the whole, I think the first approach is the most sensible though. If you find you need to do this often, consider writing a method to encapsulate it:
// TODO: Think of a better name :)
public static string SubstringBeforeFirst(string text, string delimiter)
{
int index = text.IndexOf(delimiter);
return index == -1 ? text : text.Substring(0, index);
}
You just have to test if qty__c have a point in it before calling Substring :
var pointPos = qty__c.IndexOf('.');
if (pointPos != -1)
{
qty__c = qty__c.Substring(0, pointPos);
}
Use IndexOf method on that string. If returned value is -1, there is no character that was searched.
int index = mystring.IndexOf('.');
In your code, you are not checking the returned value of IndexOf. In the case where '.' is not present in the string, an exception will be thrown because SubString has been passed -1 as second parameter.
var indexofstring=quantity.Indexof('.');
if(indexofstring!=-1)
{
quantity=quantity.SubString(0,indexofstring);
}
Assuming you are looking for the decimal point in a number, which is at offset 3 both in
'123.456' and '123', then one solution is
var index = (mystring & ".").IndexOf(".")
(Sorry about the VB, I'm not sure of C# syntax)