C#: Getting correct length of string - c#

I'm currently trying to do string comparisons - I know it's not best to do so, but I need to for this solution.
If I were parsing a line such as: Raiden: HelloWorld, I would want to extract the separate strings Raiden and HelloWorld for further use.
I currently do achieve this by performing the following:
var list = channelMessage.Split(' ', ':', '\n', '\0');
However, when printing the result and length of each item in list the HelloWorld string's length is incorrect.
Output:
Raiden | length: 6
HelloWorld | length: 11
HelloWorld's length should be 10, not 11. I'm assuming there's null characters somewhere in the line, but cannot figure out how to remove them all.
Sidenote: If I remember correctly, c#'s strings are arrays, and the last character of the array is a '\0' but I tried removing it (as seen above)
Is my assumption correct, and how can I correctly get HelloWorld's length to 10?

you're supposed to use Trim() to remove whitespaces around a string
See : https://learn.microsoft.com/en-us/dotnet/api/system.string.trim?view=netframework-4.8
This would result in
var list = channelMessage.Split(':').Select(s => s.Trim());
I'm also using the Select() from linq. This code would be similar to:
var list = channelMessage.Split(':');
var list2 = new List<string>();
foreach(string s in list)
list2.add(s.trim());

The problem is that when you split Raiden: HelloWorld on : you end up with this:
Raiden
_HelloWorld
Where the _ represents an empty whitespace.
Here's one possible solution. When I run this console app:
static void Main(string[] args)
{
var test = "Raiden: HelloWorld";
List<string> split = test.Split(':').Select(t => t.Trim()).ToList();
Console.WriteLine(split[0].Length);
Console.WriteLine(split[1].Length);
Console.ReadLine();
}
I get:
6
10

Split will likely give you trouble in this solution since it doesn't handle a huge range of input.
Something like a regex might be better because of the char ranges, something like \W+ would match any non-world sequence.
example:
Regex.Split("asdadaSD asdsad asdsad \n asdasdsd", "\\W+")

Related

how to split a string on every parenthese and keep all text into an array in c#

I'm trying to split a string on every parenthese into an array and keep all text in C#, get everything in the parenthese.
Example: "hmmmmmmmm (asdfhqwe)asasd"
Should become: "hmmmmmmmm", "(asdfhqwe)" and "asasd".
My current setup is only able to take everything inside the parentheses and discards the rest.
var output = input.Split('(', ')').Where((item, index) => index % 2 != 0).ToList();
How would i go forward to do such thing (disregarding my current code) ?
Use regrx split with positive look-ahead and look-behind and an optional space; then filter out empty strings.
var tokens = Regex
.Split(str, #"(?<=[)])\s*|\s*(?=[(])")
.Where(s => s != string.Empty)
.ToList();
Demo.
Oky so I do not know what the real string will look like in your application, but based on the provided string this will be my hack of a solution:
string sample = "hmmmmmmmm (asdfhqwe)asasd";
var result = sample.Replace("(", ",(").Replace(")", "),").Split(',');
So i replaced where the split should be with a comma, but you can use any other char that might never occur in your string, Say like the '~' could also work.
But not knowing all the required functionality, this would work for above scenario.
Try this:
string[] subString = myString.Split(new char[] { '(', ')' });

Reversing a string sentence (not necessarily space between each)

I have this string:
com.example.is-this#myname
i would like it to be
myname#this-is.example.com
using .Net, but a straight out concept or an idea would be good to.
What i'm currently doing is going over each character, find out if it's one of the "special characters" and assign all prior chars, to a variable of an array, at the end, i'm joining them all together from last to first.
is there a possible more efficient way to do this ?
This is the classic word-by-word reversal, with a small twist on delimiters. A solution to this problem is reversing each word individually, and then reversing the whole string. Do not touch delimiters when reversing words.
First step goes as follows: we find limits of each token, and reverse it in place, like this:
com.example.is-this#myname
moc.example.is-this#myname
moc.elpmaxe.is-this#myname
moc.elpmaxe.si-this#myname
moc.elpmaxe.si-siht#myname
moc.elpmaxe.si-siht#emanym
Reverse the result to get your desired output:
moc.elpmaxe.si-siht#emanym -> myname#this-is.example.com
As far as the implementation goes, you can do it by converting the string to an array of characters to make it changeable in place, and write a short helper method that lets you reverse a portion of a char array between indexes i and j. With this helper method in place, all you need to do is to find delimiters and call the helper for each delimited word, and then make one final call to reverse the entire sentence.
With little bit of Regex and Linq this is fairly simple.
Idea is that we take words and non word characters as separate token with Regex patten. Then, we just reverse it and join it.
var tokens = Regex.Matches("com.example.is-this#myname", #"\w+|\W")
.Cast<Match>()
.Select(x=>x.Value)
.Reverse();
string reversed = string.Concat(tokens);
Output: Ideone - Demo
myname#this-is.example.com
You could use the Split C# method.
The example below is from here.
using System;
class Program
{
static void Main()
{
string s = "there is a cat";
// Split string on spaces.
// ... This will separate all the words.
string[] words = s.Split(' ');
foreach (string word in words)
{
Console.WriteLine(word);
}
}
}
Is as simple as examples get.
Then you add more conditions to your Split()
string [] split = strings .Split(new Char [] {'.' , '#', '-' },
StringSplitOptions.RemoveEmptyEntries);
The RemoveEmptyEntries just removes unwanted empty entries to your array.
After that you reverse your array using the Array.Reverse method.
And then you can stitch your string back together with a Foreach loop.
As #marjan-venema mentioned in the comments you could populate a parallel array at this point with each delimiter. Reverse it, and then concatenate the string when you are using the Foreach loop at each entry.
Here's another way to do it using a List, which has a handy Insert method, as well as a Reverse method.
The Insert method lets you continue to add characters to the same index in the list (and the others after it are moved to higher indexes).
So, as you read the original string, you can keep inserting the characters at the start. Once you come to a delimeter, you add it to the end and adjust your insert position to be right after the delimeter.
When you're done, you just call Reverse and join the characters back to a string:
public static string ReverseWords(string words, char[] wordDelimeters)
{
var reversed = new List<char>();
int insertPosition = 0;
for(int i = 0; i < words.Length; i++)
{
var character = words[i];
if (wordDelimeters.Contains(character))
{
reversed.Add(character);
insertPosition = i + 1;
continue;
}
reversed.Insert(insertPosition, character);
}
reversed.Reverse();
return string.Join("", reversed);
}

Using string.ToUpper on substring

Have an assignment to allow a user to input a word in C# and then display that word with the first and third characters changed to uppercase. Code follows:
namespace Capitalizer
{
class Program
{
static void Main(string[] args)
{
string text = Console.ReadLine();
char[] delimiterChars = { ' ' };
string[] words = text.Split(delimiterChars);
string Upper = text.ToUpper();
Console.WriteLine(Upper);
Console.ReadKey();
}
}
}
This of course generates the entire word in uppercase, which is not what I want. I can't seem to make text.ToUpper(0,2) work, and even then that'd capitalize the first three letters. Only solution I can think of now that would make the word appear on one line (and I don't know if it works) is to move the capitalized letters and lowercase letters into a character array and try to get that to print all values in a modified order.
The simplest way I can think of to address your exact question as described — to convert to upper case the first and third characters of the input — would be something like the following:
StringBuilder sb = new StringBuilder(text);
sb[0] = char.ToUpper(sb[0]);
sb[2] = char.ToUpper(sb[2]);
text = sb.ToString();
The StringBuilder class is essentially a mutable string object, so when doing these kinds of operations is the most fluid way to approach the problem, as it provides the most straightforward conversions to and from, as well as the full range of string operations. Changing individual characters is easy in many data structures, but insertions, deletions, appending, formatting, etc. all also come with StringBuilder, so it's a good habit to use that versus other approaches.
But frankly, it's hard to see how that's a useful operation. I can't help but wonder if you have stated the requirements incorrectly and there's something more to this question than is seen here.
You could use LINQ:
var upperCaseIndices = new[] { 0, 2 };
var message = "hello";
var newMessage = new string(message.Select((c, i) =>
upperCaseIndices.Contains(i) ? Char.ToUpper(c) : c).ToArray());
Here is how it works. message.Select (inline LINQ query) selects characters from message one by one and passes into selector function:
upperCaseIndices.Contains(i) ? Char.ToUpper(c) : c
written as C# ?: shorthand syntax for if. It reads as "If index is present in the array, then select upper case character. Otherwise select character as is."
(c, i) => condition
is a lambda expression. See also:
Understand Lambda Expressions in 3 minutes
The rest is very simple - represent result as array of characters (.ToArray()), and create a new string based off that (new string(...)).
Only solution I can think of now that would make the word appear on one line (and I don't know if it works) is to move the capitalized letters and lowercase letters into a character array and try to get that to print all values in a modified order.
That seems a lot more complicated than necessary. Once you have a character array, you can simply change the elements of that character array. In a separate function, it would look something like
string MakeFirstAndThirdCharacterUppercase(string word) {
var chars = word.ToCharArray();
chars[0] = chars[0].ToUpper();
chars[2] = chars[2].ToUpper();
return new string(chars);
}
My simple solution:
string text = Console.ReadLine();
char[] delimiterChars = { ' ' };
string[] words = text.Split(delimiterChars);
foreach (string s in words)
{
char[] chars = s.ToCharArray();
chars[0] = char.ToUpper(chars[0]);
if (chars.Length > 2)
{
chars[2] = char.ToUpper(chars[2]);
}
Console.Write(new string(chars));
Console.Write(' ');
}
Console.ReadKey();

Select a part of string when find a character

I need to select a part of a string ,suppose i have a string like this :Hello::Hi,
I use this characters :: as a separator, so i need to separate Hello and Hi.I am using C# application form .
I googled it ,i found something like substring but it didn't help me.
Best regards
string.Split is the right method, but the syntax is a little tricky when splitting based on a string versus a character.
The overload to split on a string takes the input as an array of strings so it can be distinquished from the overload that takes an array of characters (since a string can be easily cast to an array of characters), and adds a parameter for StringSplitEntries, which you can set to None to use the default option (include "empty" entries):
string source = "Hello::Hi";
string[] splits = source.Split(new string[] {"::"}, StringSplitOptions.None);
You can split a string into multiple parts based on a semaphore using the Split function:
var stringToSearch = "Hello::Hi";
var foundItems = stringToSearch.Split(new[] {"::"},
StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < foundItems.Count(); i++)
{
Console.WriteLine("Item #{0}: {1}", i + 1, foundItems[i]);
}
// Ouput:
// Item #1: Hello
// Item #2: Hi

Regex not working in .NET

So I'm trying to match up a regex and I'm fairly new at this. I used a validator and it works when I paste the code but not when it's placed in the codebehind of a .NET2.0 C# page.
The offending code is supposed to be able to split on a single semi-colon but not on a double semi-colon. However, when I used the string
"entry;entry2;entry3;entry4;"
I get a nonsense array that contains empty values, the last letter of the previous entry, and the semi-colons themselves. The online javascript validator splits it correctly. Please help!
My regex:
((;;|[^;])+)
Split on the following regular expression:
(?<!;);(?!;)
It means match semicolons that are neither preceded nor succeeded by another semicolon.
For example, this code
var input = "entry;entry2;entry3;entry4;";
foreach (var s in Regex.Split(input, #"(?<!;);(?!;)"))
Console.WriteLine("[{0}]", s);
produces the following output:
[entry]
[entry2]
[entry3]
[entry4]
[]
The final empty field is a result of the semicolon on the end of the input.
If the semicolon is a terminator at the end of each field rather than a separator between consecutive fields, then use Regex.Matches instead
foreach (Match m in Regex.Matches(input, #"(.+?)(?<!;);(?!;)"))
Console.WriteLine("[{0}]", m.Groups[1].Value);
to get
[entry]
[entry2]
[entry3]
[entry4]
Why not use String.Split on the semicolon?
string sInput = "Entry1;entry2;entry3;entry4";
string[] sEntries = sInput.Split(';');
// Do what you have to do with the entries in the array...
Hope this helps,
Best regards,
Tom.
As tommieb75 wrote, you can use String.Split with StringSplitOptions Enumeration so you can control your output of newly created splitting array
string input = "entry1;;entry2;;;entry3;entry4;;";
char[] charSeparators = new char[] {';'};
// Split a string delimited by characters and return all non-empty elements.
result = input.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);
The result would contain only 4 elements like this:
<entry1><entry2><entry3><entry4>

Categories

Resources