if statement does not work in c# - c#

I have a fairly simple task which I want to do but something weird is happening. I just want to check if an element in a string equals zero and then set an integer accordingly.
This is my code
if (ssRow[(bar_position_row - 3)].Equals("0") && ssRow[(bar_position_row + 1)].Equals("0"))
{
back_row = 2;
front_row = 2;
}
else if (!ssRow[(bar_position_row - 3)].Equals("0") && !ssRow[(bar_position_row + 1)].Equals("0"))
{
back_row = 3;
front_row = 1;
}
else if (ssRow[(bar_position_row - 3)].Equals("0") && !ssRow[(bar_position_row + 1)].Equals("0"))
{
back_row = 2;
front_row = 1;
}
When I test my code, in several examples ssRow[(bar_position_row - 3)] and ssRow[(bar_position_row + 1)] equal zero but somehow the ssRow[(bar_position_row - 3)].Equals("0") and ssRow[(bar_position_row + 1)].Equals("0") are both FALSE. Does anyone know what my mistake is?

When you index into a string, what you get back is a char, not another string. You then compare this char to a string ("0"), and understandably get back false.
You should be comparing against '0' (a char), not "0" (a string). And since char is a value type, you can just use the == equality operator. If you had done so in the first place, this would have been a compile time error.
See example:
"abc"[0].Equals("a") //false
"abc"[0].Equals('a') //true
"abc"[0] == 'a' //true
"abc"[0] == "a" //compile-time error, can't compare char with string

I do not know the type of ssRow, if using index access on it does not return an string, then Equals("0") is doing object equality.
To fix it, consider using .ToString() first: ssRow[(bar_position_row - 3)].ToString().Equals("0")

Related

How to check for variable character in string and match it with another string of same length?

I have a rather complex issue that I'am unable to figure out.
I'm getting a set of string every 10 seconds from another process in which the first set has first 5 characters constant, next 3 are variable and can change. And then another set of string in which first 3 are variable and next 3 are constant.
I want to compare these values to a fixed string to check if the first 5 char matches in 1st set of string (ABCDE*** == ABCDEFGH) and ignore the last 3 variable characters while making sure the length is the same. Eg : if (ABCDE*** == ABCDEDEF) then condition is true, but if (ABCDE*** == ABCDDEFG) then the condition is false because the first 5 char is not same, also if (ABCDE*** == ABCDEFV) the condition should be false as one char is missing.
I'm using the * in fixed string to try to make the length same while comparing.
Does this solve your requirements?
private static bool MatchesPattern(string input)
{
const string fixedString = "ABCDExyz";
return fixedString.Length == input.Length && fixedString.Substring(0, 5).Equals(input.Substring(0, 5));
}
In last versions of C# you can also use ranges:
private static bool MatchesPattern(string input)
{
const string fixedString = "ABCDExyz";
return fixedString.Length == input.Length && fixedString[..5].Equals(input[..5]);
}
See this fiddle.
BTW: You could probably achieve the same using regex.
It's always a good idea to make an abstraction. Here I've made a simple function that takes the pattern and the value and makes a check:
bool PatternMatches(string pattern, string value)
{
// The null string doesn't match any pattern
if (value == null)
{
return false;
}
// If the value has a different length than the pattern, it doesn't match.
if (pattern.Length != value.Length)
{
return false;
}
// If both strings are zero-length, it's considered a match
bool result = true;
// Check every character against the pattern
for (int i = 0; i< pattern.Length; i++)
{
// Logical and the result, * matches everything
result&= (pattern[i]== '*') ? true: value[i] == pattern[i];
}
return result;
}
You can then call it like this:
bool b1 = PatternMatches("ABCDE***", "ABCDEFGH");
bool b2 = PatternMatches("ABC***", "ABCDEF");
You could use regular expressions, but this is fairly readable, RegExes aren't always.
Here is a link to a dotnetfiddle: https://dotnetfiddle.net/4x1U1E
If the string you match against is known at compile time, your best bet is probably using regular expressions. In the first case, match against ^ABCDE...$. In the second case, match against ^...DEF$.
Another way, probably better if the match string is unknown, uses Length, StartsWith and EndsWith:
String prefix = "ABCDE";
if (str.Length == 8 && str.StartsWith(prefix)) {
// do something
}
Then similarly for the second case, but using EndsWith instead of StartsWith.
check this
public bool Comparing(string str1, string str2)
=> str2.StartWith(str1.replace("*","")) && str1.length == str2.Length;

convert string to int error in c#

Hello I am trying to convert String to Integer.
The code below shows a part from where I am trying to convert my string to integer.
if (other.gameObject.CompareTag("PickUp"))
{
if ( checkpointboolean == false)
{
string pickupName = other.ToString(); //other = Pickup4
//Remove first 6 letters thus remaining with '4'
string y = pickupName.Substring(6);
print(y); // 4 is being printed
int x = 0;
int.TryParse(y, out x);
print (x); // 0 is being printed
I also tried the below code and instead of '0' I am getting the following error:
if (other.gameObject.CompareTag("PickUp"))
{
if ( checkpointboolean == false)
{
//Get Object name ex: Pickup4
string pickupName = other.ToString();
//Remove first 6 letters thus remaining with '4'
string y = pickupName.Substring(6);
print(y);
int x = int.Parse(y);
FormatException: Input string was not in the correct format
System.Int32.Parse (System.String s)
int.TryParse returns a boolean, true if it succeeded and false if not. You need to wrap this in a if block and do something with that logic.
if(int.TryParse(y, out x))
print (x); // y was able to be converted to an int
else
// inform the caller that y was not numeric, your conversion to number failed
As far as why your number is not converted I could not say until you post what the string value is.
Your first attempt is the best for this case, that code works fine, The int.TryParse() giving 0 to the out parameter and returns false means the conversion is failed. The input string is not in the correct format/ it cannot be converted to an integer. You can check this by using the return value of the int.TryParse(). For this what you need to do is :-
if(int.TryParse(y, out x))
print (x); //
else
print ("Invalid input - Conversion failed");
First of all, ToString() usually uses for debug purpose so there's no guarantee that
other.ToString()
will return the expected "Pickup4" in the next version of the software. You, probably, want something like
int x = other.gameObject.SomeProperty;
int x = other.SomeOtherProperty;
int x = other.ComputePickUp();
...
If you, however, insist on .ToString() you'd rather not hardcode six letters (the reason is the same: debug information tends to change from version to version), but use regular expressions or something:
var match = Regex.Match(other.ToString(), "-?[0-9]+");
if (match.Success) {
int value;
if (int.TryParse(match.Value, out value))
print(value);
else
print(match.Value + " is not an integer value");
}
else
print("Unexpected value: " + other.ToString());

cannot be assigned to -- it is read only - C#

public struct Osoba{
public string nazwisko;
[...]
}
for (int k = 0; k < l; k++)
{
dlugosc = osoba[k].nazwisko.Length;
[...]
if (c[0] == 's' && c[1] == 'k' && c[2] == 'i')
{
osoba[k].nazwisko[dlugosc - 3] = '*';
osoba[k].nazwisko[dlugosc - 2] = '*';
osoba[k].nazwisko[dlugosc - 1] = '*';
}
}
Hello there, I keep trying to replace 3 last letters of string, but i get this error:
Property or indexer 'string.this[int]' cannot be assigned to -- it is
read only\
I tried to google it, the solution was mostly adding getters and setters (i've yet to learn about it) but it didn't help me. Why can't I modify my string even thought i set everything as public?
Strings are immutable.You can't change a string after you created it.You need to create a new string and assign it back:
osoba[k].nazwisko = osoba[k].nazwisko.Substring(0, dlugosc - 3) + "***";
Strings are immutable in .NET. It's quite unclear what you are trying to achieve but if you want to directly manipulate the contents you could use a char array instead:
public struct Osoba
{
public char[] nazwisko;
[...]
}

Selecting a specific item in listbox

I have 6 items in my listbox.
I want to it so that if I click the first 2 in the listbox I can set a random number. I don't need to know how make a random number.
I thought it would be something like this:
if (listBox1.SelectedIndex = 1)
{
int no1 = random.Next(10, 50);
}
Just after 'if' I see the following error:
Cannot implicitly convert type 'int' to 'bool'
Should be: if (listBox1.SelectedIndex == 1)
The = operator is assignment, == is equality.
You need to use two equal signs to check for equality.
if (listBox1.SelectedIndex == 1)
{
int no1 = random.Next(10, 50);
}
You can read more about C# equality on MSDN.
Yes in case of int you can't use = operator to check equality you just need to check using == operator, ok in the case of bool compiler can't give any error but it can resign.mean to say.
if (listBox1.SelectedIndex == 1)
{
int no1 = random.Next(10, 50);
}
it's correct one in case of Bool
suppose you have to write.
bool test=false;
if(test=true)
{
//some code goes here
}
it won't give you compiler error it will reassign test.

Is it possible to convert vb6 "Val()" to c#?

I am currently converting vb and vb.net to c# but have an issue. I would strongly like not to use the visualbasic dlls in the converted code and have been doing this fine so far.
But this code
Dim x as Double 'this was error saying it was integer
x = Val("1 23 45 x 6") ''#x is 12345
x = Val("1..23") ''#x is 1.23
x = Val("1 1,,,,,2,2..3") ''#x is 1122.3
Does not work the same as vb6 even with using "Val" from the visualbasic.conversion.dll Is there anyone that has solved this to work the same? A c# solution would be best.
None of the above seemed to satisfy my needs, so I wrote the following:
public static Double Val(string value)
{
String result = String.Empty;
foreach (char c in value)
{
if (Char.IsNumber(c) || (c.Equals('.') && result.Count(x => x.Equals('.')) == 0))
result += c;
else if (!c.Equals(' '))
return String.IsNullOrEmpty(result) ? 0 : Convert.ToDouble(result);
}
return String.IsNullOrEmpty(result) ? 0 : Convert.ToDouble(result);
}
Results of the test data:
"0 1 5.2123 123.123. 1 a" returns 15.21233123
" 1 5.2123 123a" returns 15.21233123
"a1 5.2123 123.123. 1 a" returns 0
"" returns 0
I know nothing of this VisualBasic.Conversion.dll (and neither does google), but the Microsoft.VisualBasic namespace (in Microsoft.VisualBasic.dll) is part of the core framework and perfectly fine and acceptable to use from C#. There are other nice gems in there as well (ie TextFieldParser), but this should have the exact Val() implementation you need.
If this is the library you've already tried and it doesn't seem right, then I'd go take another look at the unit tests on it.
Outside of this, the accepted ways in C# for converting strings to integers are int.Parse(), int.TryParse(), and Convert.ToInt32(). But, like it or not, the Val() function from the Microsoft.VisualBasic.dll library is the closest match you're going to find for your code's existing behavior.
Check out this site: http://www.dreamincode.net/forums/topic/36064-val-replacement/ where others give an example how to implement your own Val() function.
You could use the Convert static class. It's pretty close to Val() but you need to specify the convert to type. It's in the System namespace.
E.g.:
int x = Convert.ToInt32("23");
int y = Convert.ToDouble("23.342");
http://msdn.microsoft.com/en-us/library/system.convert(v=vs.71).aspx
There is no exact equivalent of vb6 val function in C#. But this function can be used by using Microsoft.VisualBasic namespace in C#.
To use val() function in C# add Microsoft.VisualBasic namespace and use following code:
Conversion.Val("09sdf");
From your examples it could look similar to this. But since I don't know the VB val specification it might not work on all strings correctly.
Decimal ParseNumerString(string s)
{
Decimal value=0;
Decimal multiplier=1;
bool decimalPart=false;
foreach(char c in s)
{
if(IsDigit(c))
{
int i=ParseDigit(c);
if(!decimalPart)
{
value=value*10+i;
}
else
{
muliplier/=10;
value=value+multiplier*i;
}
if(c=='.')
decimapPart=true;
}
return value;
}
This is pseudocode you need to implement parse digit and is digit yourself(trivial). I chose Decimal as internal representation because that way I don't get strange rounding errors in the fractional part.
Had the same issue, started with #ericosg 's answer, then realized I needed Negative Numbers and Scientific Notation
namespace VB6
{
public class Helper
{
public static double Val(object value)
{
double returnVal = 0;
string sToParse = value.ToString();
string result = string.Empty;
string num = string.Empty; //In the case of scientific notation e.g. 3e5 = 300000
foreach (char c in sToParse)
{
if (result.Length == 0 && c.Equals('-'))//negative numbers
result += c;
else if (Char.IsNumber(c) || (c.Equals('.') && result.Count(x => x.Equals('.')) == 0))
result += c;
else if ((c.Equals('e') || c.Equals('E')) && num.Length == 0 && result.Length != 0) //scientific notation
{
num = result;
result = string.Empty;
}
else if (!c.Equals(' '))
{
break;
}
}
if (num.Length > 0)
{
//scientific notation
double fSignificantFigures = string.IsNullOrEmpty(result) || result == "-" ? 1 : Math.Pow(10, Convert.ToDouble(result));
returnVal = num == "-" ? 0 : Convert.ToDouble(num) * fSignificantFigures;
}
else
{
returnVal = string.IsNullOrEmpty(result) || result == "-" ? 0 : Convert.ToDouble(result);
}
return returnVal;
}
}
}

Categories