The below snippet takes a string as input. What I am trying is to get middle 2 elements of the string if the length is even.
string input = "confir";
string op = "";
op = input.Substring((input.Length - 1) / 2,input.Length/2 -1);//logic
Console.WriteLine(op);//display the output
Output for above snippet is nf.
When input is changed to confirme, output should be fi and not fir
How do I generalize? What is the error in the logic?
Second argument of String.Substring is a length of substring, not index like in Java. So if you need to get substring of two characters, pass 2:
string input = "confirme";
string op = input.Substring((input.Length - 1) / 2, 2);
BTW you should handle case when string is less than 2 characters long:
string op = input.Substring((input.Length - 1) / 2, Math.Min(input.Length, 2));
Tests:
input | op |
---------------------
"" | "" |
"c" | "c" |
"co" | "co" |
"con" | "on" |
"conf" | "on" |
"confir" | "nf" |
"confirme" | "fi" |
string input = "confir";
if(input.Length % 2 == 0)
Console.WriteLine(input.Substring((input.Length / 2)-1, 2));
That should give you the expected result.First check whether the string length is even then instead of (input.Length - 1) / 2, divide length by 2 and subtract 1,then take two characters like this: (input.Length / 2) - 1
Problem : you are providing total length of the string as second argument to the Substring() method.
Solution : Substring() method takes total number of characters tobe removed starting from first argument .
From MSDN : Substring(Int32, Int32)
Retrieves a substring from this instance. The substring starts at a
specified character position and has a specified length.
Replace This:
op = input.Substring((input.Length - 1) / 2,input.Length/2 -1);//logic
With This:
op = input.Substring((input.Length - 1) / 2,2);//logic
Suggestion : you need to check for Empty String and for Even number of charatcters in String.
Complete Code:
string input = "confirme";
string op = "";
if (input.Length > 0 && input.Length % 2 == 0)
{
op = input.Substring((input.Length - 1) / 2, 2);//logic
Console.WriteLine(op);//display the output
}
Related
I am trying to get the index of a each char in the text "ABCDCEF" (textBox.text). The problem is that the first 'C' index is 2 and the second C index is 4 but the second 'C' index in the result is 2 too.
This is the code:
foreach (char character in textBox1.Text)
{
MessageBox.Show(character + " - " + textBox1.Text.IndexOf(character));
}
Result:
char - index
A - 0
B - 1
C - 2
D - 3
C - 2
E - 5
F - 6
The correct result should be:
char - index
A - 0
B - 1
C - 2
D - 3
C - 4
E - 5
F - 6
Why it's happening?
Thanks
string.IndexOf returns first occurrence of a character, that's why it returns index 2 for c lookup.
MSDN Says,
Reports the zero-based index of the first occurrence of a specified
Unicode character or string within this instance. The method returns
-1 if the character or string is not found in this instance.
You could convert it to for loop and get index for each character.
for(int i=0;i<textBox1.Text.Length;i++)
{
MessageBox.Show(textBox1.Text[i] + " - " + i);
}
How to format a number such that first 6 digits and last 4 digits are not hidden
such that 111111111111111 looks like 111111****1111
You can also use LINQ, substituting chars with indexes more than 5 and less than number.Length - 4 with *:
string number = "111111111111111";
string res = new string(number.Select((c, index) => { return (index <= 5 || index >= number.Length - 4) ? c : '*'; }).ToArray());
Console.WriteLine(res); // 111111*****1111
One simple way to do this is to slit the input..
int number = 111111111111111;
string firstsix = number.ToString().Substring(0,6) //gets the first 6 digits
string middlefour = number.ToString().Substring(6,4) //gets the next 4
string rest = number.ToString().Substring(10, number.ToString().Lenght) //gets the rest
string combined = firstsix + "****" +rest;
You need to use \G anchor in-order to do a continuous string match.
string result = Regex.Replace(str, #"(?:^(.{6})|\G).(?=.{4})", "$1*");
DEMO
IDEONE
I am learning validation expressions and have attempted to write one to check a decimal like the example below but I am having some issues.
The number to validate is like this:
00.00 (any 2 numbers, then a ., then any 2 numbers)
This is what I have:
^[0-9]{2}[.][0-9]{2}$
This expression returns false but from a tutorial I read I was under the understanding that it should be written like this:
^ = starting character
[0-9] = any number 0-9
{2} = 2 numbers 0-9
[.] = full stop
$ = end
Use the right tool for the job. If you're parsing decimals, use decimal.TryParse instead of Regex.
string input = "00.00";
decimal d;
var parsed = Decimal.TryParse(input, out d);
If the requirement is to always have a 2 digits then a decimal point then 2 digits you could do:
var lessThan100 = d < 100m;
var twoDecimals = d % 0.01m == 0;
var allOkay = parsed && lessThan100 && twoDecimals;
So our results are
Stage | input = "" | "abc" | "00.00" | "123" | "0.1234"
-------------------------------------------------------------
parsed | false | false | true | true | true
lessThan100 | - | - | true | false | true
twoDecimals | - | - | true | - | false
Although if you really need it to be that exact format then you could do
var separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
var allOkay = isOkay && input.Length == 5 && input[2] == separator;
If you absolutely have to use Regex then the following works as required:
Regex.IsMatch("12.34", #"^([0-9]{2}\.[0-9]{2})$")
Regex explanation:
^ - start of string
() - match what's inside of brackets
[0-9]{2} exactly 2 characters in the range 0 - 9
\. - full stop (escaped)
$ - end of string
I Have a string array with 5 values, i want the program to loop even though i don't enter a value for the arrays. If I split the arrays without inserting anything (pressing ..... (5 times "." to split the array) then it doesn't crash it will just loop. But if i just hit enter, then the program crashes.
Is there a way to fix the loop so that even though there is no kind of input, that it won't crash? (It also crashes if you don't complete all 5 values.)
Net = Console.ReadLine();
string[] oktet = new string[5];
oktet = Net.Split('.', '/');
temp = oktet[0]; //inputs value of array in temp
NaN = int.TryParse(temp, out Net0);
temp = oktet[1];
NaN = int.TryParse(temp, out Net1);
temp = oktet[2];
NaN = int.TryParse(temp, out Net2);
temp = oktet[3];
NaN = int.TryParse(temp, out Net3);
temp = oktet[4];
NaN = int.TryParse(temp, out subnet);
}
while (!NaN | Net0 > 255 | Net0 < 0 | Net1 > 255 | Net1 < 0 | Net2 > 255 | Net2 < 0 | Net3 > 255 | Net3 < 0 | subnet > 32 | subnet < 0);
I know it's pretty amateur, but hey, we're here to learn right? :)
Thanks in advanced!
You can try to do something like this:
string[] oktet = Net.Split('.', '/'); // size array according to input
if (oktet.Length != 5) continue; // reloop on bad input
Those two lines of code replace these:
string[] oktet = new string[5];
oktet = Net.Split('.', '/');
I would just use some command line option library if you could (unless this is homework where you need to learn how to validate input, parse, etc.). See NDesk.Options (http://www.ndesk.org/Options), available via Nuget as well. See the following for required options: How to enforce required command-line options with NDesk.Options?
var userInput = Console.ReadLine();
var userInputSplit = userInput.Split('.', '/');
var numbers = userInputSplit.Select(word =>
{
int result;
if (byte.TryParse(word, out result))
return (byte?)result;
return (byte?)null; });
});
var inputComplete = number.Where(number => number.HasValue).Count() == 4;
The problem is that your variable oktet isn't an array of 5, because you're assigning something else in it.
string[] oktet = new string[5]; // Assigns an array of 5
oktet = Net.Split('.', '/'); //assigns the result of the split to the variable
So, oktet is has the result of the split, and its length.
BTW, Classes start with a capital letter, and the variables should start with a small letter.
Coding standards will make the code more readable, and will help you tell the difference between items.
I have a block of text that im taking from a Gedcom (Here and Here) File
The text is flat and basically broken into "nodes"
I am splitting each node on the \r char and thus subdividing it into each of its parts( amount of "lines" can vary)
I know the 0 address will always be the ID but after that everything can be anywhere so i want to test each Cell of the array to see if it contains the correct tag for me to proccess
an example of what two nodes would look like
0 #ind23815# INDI <<<<<<<<<<<<<<<<<<< Start of node 1
1 NAME Lawrence /Hucstepe/
2 DISPLAY Lawrence Hucstepe
2 GIVN Lawrence
2 SURN Hucstepe
1 POSITION -850,-210
2 BOUNDARY_RECT (-887,-177),(-813,-257)
1 SEX M
1 BIRT
2 DATE 1521
1 DEAT Y
2 DATE 1559
1 NOTE * Born: Abt 1521, Kent, England
2 CONT * Marriage: Jane Pope 17 Aug 1546, Kent, England
2 CONT * Died: Bef 1559, Kent, England
2 CONT
1 FAMS #fam08318#
0 #ind23816# INDI <<<<<<<<<<<<<<<<<<<<<<< Start of Node 2
1 NAME Jane /Pope/
2 DISPLAY Jane Pope
2 GIVN Jane
2 SURN Pope
1 POSITION -750,-210
2 BOUNDARY_RECT (-787,-177),(-713,-257)
1 SEX F
1 BIRT
2 DATE 1525
1 DEAT Y
2 DATE 1609
1 NOTE * Born: Abt 1525, Tenterden, Kent, England
2 CONT * Marriage: Lawrence Hucstepe 17 Aug 1546, Kent, England
2 CONT * Died: 23 Oct 1609
2 CONT
1 FAMS #fam08318#
0 #ind23817# INDI <<<<<<<<<<< start of Node 3
So a when im done i have an array that looks like
address , string
0 = "1 NAME Lawrence /Hucstepe/"
1 = "2 DISPLAY Lawrence Hucstepe"
2 = "2 GIVN Lawrence"
3 = "2 SURN Hucstepe"
4 = "1 POSITION -850,-210"
5 = "2 BOUNDARY_RECT (-887,-177),(-813,-257)"
6 = "1 SEX M"
7 = "1 BIRT "
8 = "1 FAMS #fam08318#"
So my question is what is the best way to search the above array to see which Cell has the SEX tag or the NAME Tag or the FAMS Tag
this is the code i have
private int FindIndexinArray(string[] Arr, string search)
{
int Val = -1;
for (int i = 0; i < Arr.Length; i++)
{
if (Arr[i].Contains(search))
{
Val = i;
}
}
return Val;
}
But it seems inefficient because i end up calling it twice to make sure it doesnt return a -1
Like so
if (FindIndexinArray(SubNode, "1 BIRT ") != -1)
{
// add birthday to Struct
I.BirthDay = SubNode[FindIndexinArray(SubNode, "1 BIRT ") + 1].Replace("2 DATE ", "").Trim();
}
sorry this is a longer post but hopefully you guys will have some expert advice
Can use the static method FindAll of the Array class:
It will return the string itself though, if that works..
string[] test = { "Sex", "Love", "Rock and Roll", "Drugs", "Computer"};
Array.FindAll(test, item => item.Contains("Sex") || item.Contains("Drugs") || item.Contains("Computer"));
The => indicates a lamda expression. Basically a method without a concrete implementation.
You can also do this if the lamda gives you the creeps.
//Declare a method
private bool HasTag(string s)
{
return s.Contains("Sex") || s.Contains("Drugs") || s.Contains("Computer");
}
string[] test = { "Sex", "Love", "Rock and Roll", "Drugs", "Computer"};
Array.FindAll(test, HasTag);
What about a simple regular expression?
^(\d)\s=\s\"\d\s(SEX|BIRT|FAMS){1}.*$
First group captures the address, second group the tag.
Also, it might be quicker to dump all array items into a string and do your regex on the whole lot at once.
"But it seems inefficient because i end up calling it twice to make sure it doesnt return a -1"
Copy the returned value to a variable before you test to prevent multiple calls.
IndexResults = FindIndexinArray(SubNode, "1 BIRT ")
if (IndexResults != -1)
{
// add birthday to Struct
I.BirthDay = SubNode[IndexResults].Replace("2 DATE ", "").Trim();
}
The for loop in method FindIndexinArray shd break once you find a match if you are interested in only the first match.