Central/middle letter of a string.(methods) - c#

I need to solve the following question which i can't get to work by myself(newbie^^)..:
Ok, the question: Create a method which will print the central letter of a string (given as a parameter). I need to use the property lenght to determine the lenght.
So for example the string: Books. the middle/central letter is o.
Hope its a bit clear..
Thanks in advance.
Edit: I know how to determine the lenght of the string. Now the problem is to divide the word and then write down the next letter or something.

Here are some tips:
1. Type string has a Length property.
2 .If you know the index of the character you want, you can ask for it using: myString[index].
3. Knowing what to do with string that has even number of characters is necessary to answer that question.
4. Consider integer devision.
That should get you started.

string middleLetter(string arg)
{
return arg[arg.Length >> 1];
}

public static string FindMiddleChar(string s)
{
int middleChar = s.Length / 2;
if (s.Length > 2)
{
if (s.Length % 3 == 0)
{
if (s.Length <= 3)
{
return s[middleChar].ToString();
}
return s[middleChar - 1] + s[middleChar].ToString();
}
else if (s.Length % 3 != 0)
{
if (s.Length <= 4)
{
return s[middleChar - 1] + s[middleChar].ToString();
}
return s[middleChar].ToString();
}
}
return "Error, the input string must contain at least three characters.";
}

Related

C# locating where the * is in a string separated by pipes

I have to find where a * is at when it could be none at all , 1st position | 2nd position | 3rd position.
The positions are separated by pipes |
Thus
No * wildcard would be
`ABC|DEF|GHI`
However, while that could be 1 scenario, the other 3 are
string testPosition1 = "*|DEF|GHI";
string testPosition2 = "ABC|*|GHI";
string testPosition3 = "ABC|DEF|*";
I gather than I should use IndexOf , but it seems like I should incorporate | (pipe) to know the position ( not just the length as the values could be long or short in each of the 3 places. So I just want to end up knowing if * is in first, second or third position ( or not at all )
Thus I was doing this but i'm not going to know about if it is before 1st or 2nd pipe
if(testPosition1.IndexOf("*") > 0)
{
// Look for pipes?
}
There are lots of ways you could approach this. The most readable might actually just be to do it the hard way (i.e. scan the string to find the first '*' character, keeping track of how many '|' characters you see along the way).
That said, this could be a similarly readable and more concise:
int wildcardPosition = Array.IndexOf(testPosition1.Split('|'), "*");
Returns -1 if not found, otherwise 0-based index for which segment of the '|' delimited string contains the wildcard string.
This only works if the wildcard is exactly the one-character string "*". If you need to support other variations on that, you will still want to split the string, but then you can loop over the array looking for whatever criteria you need.
You can try with linq splitting the string at the pipe character and then getting the index of the element that contains just a *
var x = testPosition2.Split('|').Select((k, i) => new { text = k, index = i}).FirstOrDefault(p => p.text == "*" );
if(x != null) Console.WriteLine(x.index);
So the first line starts splitting the string at the pipe creating an array of strings. This sequence is passed to the Select extension that enumerates the sequence passing the string text (k) and the index (i). With these two parameters we build a sequences of anonymous objects with two properties (text and index). FirstOrDefault extract from this sequence the object with text equals to * and we can print the property index of that object.
The other answers are fine (and likely better), however here is another approach, the good old fashioned for loop and the try-get pattern
public bool TryGetStar(string input, out int index)
{
var split = input.Split('|');
for (index = 0; index < split.Length; index++)
if (split[index] == "*")
return true;
return false;
}
Or if you were dealing with large strings and trying to save allocations. You could remove the Split entirely and use a single parse O(n)
public bool TryGetStar(string input, out int index)
{
index = 0;
for (var i = 0; i < input.Length; i++)
if (input[i] == '|') index++;
else if (input[i] == '*') return true;
return false;
}
Note : if performance was a consideration, you could also use unsafe and pointers, or Span<Char> which would afford a small amount of efficiency.
Try DotNETFiddle:
testPosition.IndexOf("*") - testPosition.Replace("|","").IndexOf("*")
Find the index of the wildcard ("*") and see how far it moves if you remove the pipe ("|") characters. The result is a zero-based index.
From the question you have the following code segment:
if(testPosition1.IndexOf("*") > 0)
{
}
If you're now inside the if statement, you're sure the asterisk exists.
From that point, an efficient solution could be to check the first two chars, and the last two chars.
if (testPosition1.IndexOf("*") > 0)
{
if (testPosition1[0] == '*' && testPosition[1] == '|')
{
// First position.
}
else if (testPosition1[testPosition.Length - 1] == '*' && testPosition1[testPosition.Length - 2] == '|')
{
// Third (last) position.
}
else
{
// Second position.
}
}
This assumes that no more than one * can exist, and also assumes that if an * exist, it can only be surrounded by pipes. For example, I assume an input like ABC|DEF|G*H is invalid.
If you want to remove this assumptions, you could do a one-pass loop over the string and keeping track with the necessary information.

C# writeline cap

I am writing a program that writes to a file that requires specific positions:
it looks something like:
writer.WriteLine("{0,-3}{1,-5}{2,-30}", data1, data2, data3);
The positions that it starts is correct however, if data1 exceeds 3 character, it pushes the format by the exceeded amount,
Is there a way to make data1 cap at 3 characters and ignore any excess characters using the writeline format?
If I understood correctly, you should "safely substring" (Substring throws an exception if you choose a length greater than the string length) your strings to the desidered lenght.
public static string SafeSubstring(this string text, int start, int length)
{
return text.Length <= start ? string.Empty
: text.Length - start <= length ? text.Substring(start)
: text.Substring(start, length);
}
Then, for example:
writer.WriteLine("{0,-3}{1,-5}{2,-30}",
data1.SafeSubstring(0, 3),
data2.SafeSubstring(0, 3),
data3.SafeSubstring(0, 3));
Use string.Substring. This code trims the string if it's longer than 3 characters:
Console.WriteLine("{0,-3}{1,-5}{2,-30}",
data1.Substring(0,data1.Length > 3 ? 3 : data1.Length),
data2, data3);
You can't solve this with formatting alone, but you can implement a (extension) method:
public static string ToLength(this object value, int length) {
if (length == 0)
return "";
else if (null == value)
return new string(' ', Math.Abs(length));
string v = value.ToString();
if (v.Length >= Math.Abs(length))
return v.Substring(0, Math.Abs(length));
else if (length < 0)
return v.PadRight(-length);
else
return v.PadLeft(length);
}
Then use it
writer.WriteLine("{0}{1}{2}",
data1.ToLength(-3),
data2.ToLength(-5),
data3.ToLength(-30));
I've implemented extension method for object, not string since you may want to put any object to stream.

Split a string by length with added condition [duplicate]

This question already has answers here:
Word wrap a string in multiple lines
(7 answers)
How do I split a string by a multi-character delimiter in C#?
(10 answers)
Closed 6 years ago.
I want to split a string by a certain length, but I also want to make sure that it's a full word. For example, if I had:
string str = "Hello I have a dog ";
and I wanted to split it up into chunks of 5 I would do something like this (which I got from Split String into smaller Strings by length variable):
public IEnumerable<string> SplitByLength( string s, int length)
{
for (int i = 0; i < s.Length; i += length)
{
if (i + length <= s.Length)
{
yield return s.Substring(i, length);
}
else
{
yield return s.Substring(i);
}
}
}
but that would result in output like
"Hello"
"I Hav"
"e a d"
"og"
How could I adapt it so that it would split after 5 or after a whitespace? So I would get:
"Hello"
"I"
"Have"
It's not the best example but it's the best I could come up with off the top of my head. The reason I need it is that I'm displaying the results on a web page, and after a certain amount of words, it gets difficult to read due to a background image, so when it hits the limit it breaks a line but I don't want half of a word on one line and the other half on the next line.
You should use an if/else
if (i + length <= s.Length)
{
yield return s.Substring(i, length);
}
else if(s[i] == ' ')
{
yield return s.Substring(i, s.IndexOf(" ",i) - i);
}
else
{
yield return s.Substring(i);
}

C# string toCharArray out of range exception

I came across this issue while I was fixing someone else's code. apparently they were trying to control digits after the decimal point like this:
public static bool check_count(double d)
{
string str = d.ToString();
bool b = true;
if (str.IndexOf('.'))
{
char[] ch = str.ToCharArray(str.IndexOf('.'), str.Length - 1);
if (ch.Length > 5)
b = false;
}
return b;
}
I wasn't going to bother myself fixing that since I'm replacing it with regular expressions but it made me curious. the ToCharArray is throwing ArgumentOutOfRangeException when it shouldn't(?!)
let's say
string str = "20.222";
Console.WriteLine(str);
int index = str.IndexOf('.');
if (index > -1)
{
Console.WriteLine(index);
Console.WriteLine(str.Length-1);
char[] ch = str.ToCharArray(index, str.Length - 1);
}
output:
20.222
2
5
live demo [here]
so the string is 6 chars long and the start index is 2, what argument is out of what range?
I feel lost in this .. any ideas?
thanks
what argument is out of what range?
Well, I'd expect the exception to tell you that - but I'd also expect it to be the second argument. (EDIT: Looking at the exception you actually get, even from .NET, it's actually blaming the first argument. Admittedly it's the combination of the first and second arguments which is invalid, but it's more sensible to blame the second one in this case, as the first one is valid on its own.)
Look at the documentation - the second argument is the length, not the end index. So I suspect you want something like:
char[] ch = str.ToCharArray(index, str.Length - index);
Or to get just the digits after the .:
char[] ch = str.ToCharArray(index + 1, str.Length - index - 1);

Input string was not in correct form

Im really bad with c# i have only really the basic knowladge of c# i have this piece of code but i cant get it to work probelly debugger says the problem is here http://puu.sh/2h2wV the code is here this is im sorry this is probally such an easy mistake
i had other code true,was my old programm :(
Console.WriteLine("Sisesta esimene arv vahemikus 10-20");
vastus1 = int.Parse(Console.ReadLine());
Console.WriteLine("sisesta teine arv vahemikus 20-32");
vastus2 = int.Parse(Console.ReadLine());
Console.WriteLine("Vastus {0}", vastus2 - vastus1);
string tekst1 = Console.ReadLine();
vastus3 = int.Parse(tekst1); <------ debugger says problem is here
}
while ((vastus1 < 1 || vastus2 < 12));
if (vastus3 >= 3 && vastus3 >= 5)
{
Console.WriteLine("On Kevad");
{
if (vastus3 >= 6 && vastus3 >= 8)
{
Console.WriteLine("on suvi");
}
}
if (vastus3 >= 9 && vastus3 >= 11)
{
Console.WriteLine("on sügis");
}
if (vastus3 >= 11 && vastus3 >= 2)
{
Console.WriteLine("on talv");
}
}
}
}
}
Well the error says it all really
The input string was not in the right format
In the context of what you're doing, this means that whatever you've typed into the console which you're passing directly to int.Parse cannot be parsed as an int.
If you expect that sometimes what is typed in to the console to not be numeric you could use int.TryParse to ascertain whether it is valid.
int vastus3 = 0;
while(!int.TryParse(Console.ReadLine(),out vastus3 ))
{
Console.WriteLine("Invalid number, try again!");
}
// here "vastus3" will have your integer
This can go into your code exactly where your current line which fails is.
Jamiec's explanation is correct. If the integers you are looking for always occur in the same format at the end of the string you could use Substring to get the specific characters then do your comparison checks.
Here is an example on how to remove characters from the end of a string using Substring.
Substring a string from the end of the string
And the msdn
http://msdn.microsoft.com/en-us/library/system.string.substring%28v=vs.71%29.aspx

Categories

Resources