How to read between a specified character in a string? - c#

I was trying to create a list from a user input with something like this:
Create newlist: word1, word2, word3, etc...,
but how do I get those words one by one only by using commas as references going through them (in order) and placing them into an Array etc? Example:
string Input = Console.ReadLine();
if (Input.Contains("Create new list:"))
{
foreach (char character in Input)
{
if (character == ',')//when it reach a comma
{
//code goes here, where I got stuck...
}
}
}
Edit: I didn`t know the existence of "Split" my mistake... but at least it would great if you could explain me to to use it for the problem above?

You can use this:
String words = "word1, word2, word3";
List:
List<string> wordsList= words.Split(',').ToList<string>();
Array:
string[] namesArray = words.Split(',');

#patrick Artner beat me to it, but you can just split the input with the comma as the argument, or whatever you want the argument to be.
This is the example, and you will learn from the documentation.
using System;
public class Example {
public static void Main() {
String value = "This is a short string.";
Char delimiter = 's';
String[] substrings = value.Split(delimiter);
foreach (var substring in substrings)
Console.WriteLine(substring);
}
}
The example displays the following output:
Thi
i
a
hort
tring.

Related

How do I use .ToUpper or .ToLower on a certain word in a big sentence?

string testSentence = "this is a test sentence and I WANT TO SEE HOW IT WILL LOOK LIKE hoping this part is big";
int firstLetter = testSentence.IndexOf("this");
int length = "this is a test sentence and".Length;
string upperSentence = testSentence.Substring(firstLetter, length).ToUpper();
int secondLetter = testSentence.IndexOf(" I");
int length2 = " I WANT TO SEE HOW IT WILL LOOK LIKE".Length;
string lowerSentence = testSentence.Substring(secondLetter, length2).ToLower();
int thirdSentence = testSentence.IndexOf(" hoping");
int length1 = " hoping this part is big".Length;
string get = testSentence.Substring(thirdSentence, length1).ToUpper();
Console.WriteLine(upperSentence + lowerSentence + get);
Can somebody please tell me how would you capitalize in all big or small letters only one word in the middle of the sentence? For example, make the word ''LOOK'' in small case letters. Does the ''.Length'' call has to be used or is there a different way than literally typing the word or part of the sentence that I want to convert to upper or lower cases?
The problem I have with this is, I cannot isolate just one word and make it low/big letters because then the rest of the string after the particular word is also in the lower/upper cases
In line with #Franck's advice, think about the problem as a human. You have three things:
a sentence
words that you want to be big
words that you want to be small
The sentence can really be broken down into a collection of words (ignoring punctuation). You want to go through the collection of words and change some of them to be uppercase and some of them to be lowercase - all the rest of the words you want to leave as they are.
Here is some code that does this:
using System;
using System.Linq;
public class Program
{
public static void Main()
{
// modify these as you please
string testSentence = "this is a test sentence and I WANT TO SEE HOW IT WILL LOOK LIKE hoping this part is big";
string[] wordsToUpperCase = new string[] { "hoping", "test" };
string[] wordsToLowerCase = new string[] { "look", "is" };
// start processing
// split the sentence into words
string[] wordsInSentence = testSentence.Split(' ');
// a List to hold the reworked words
var outputWords = new System.Collections.Generic.List<string>();
// process the words
foreach (string currentWord in wordsInSentence)
{
// check the wordsToUpperCase array for the current word
bool shouldUpperCaseThisWord = wordsToUpperCase.Any(stringToTest => stringToTest.Equals(currentWord, StringComparison.CurrentCultureIgnoreCase));
// check the wordsToLowerCase array for the current word
bool shouldLowerCaseThisWord = wordsToLowerCase.Any(stringToTest => stringToTest.Equals(currentWord, StringComparison.CurrentCultureIgnoreCase));
// add the current word to the output list
if (shouldUpperCaseThisWord)
outputWords.Add(currentWord.ToUpper());
else if (shouldLowerCaseThisWord)
outputWords.Add(currentWord.ToLower());
else
outputWords.Add(currentWord);
}
string finalOutput = String.Join(" ", outputWords);
Console.WriteLine(finalOutput);
}
}

C# Method to Check if a String Contains Certain Letters

I'm trying to create a method which takes two parameters, "word" and "input". The aim of the method is to print any word where all of its characters can be found in "input" no more than once (this is why the character is removed if a letter is found).
Not all the letters from "input" must be in "word" - eg, for input = "cacten" and word = "ace", word would be printed, but if word = "aced" then it would not.
However, when I run the program it produces unexpected results (words being longer than "input", containing letters not found in "input"), and have coded the solution several ways all with the same outcome. This has stumped me for hours and I cannot work out what's going wrong. Any and all help will be greatly appreciated, thanks. My full code for the method is written below.
static void Program(string input, string word)
{
int letters = 0;
List<string> remaining = new List<string>();
foreach (char item in input)
{
remaining.Add(item.ToString());
}
input = remaining.ToString();
foreach (char letter in word)
{
string c = letter.ToString();
if (input.Contains(c))
{
letters++;
remaining.Remove(c);
input = remaining.ToString();
}
}
if (letters == word.Length)
{
Console.WriteLine(word);
}
}
Ok so just to go through where you are going wrong.
Firstly when you assign remaining.ToString() to your input variable. What you actually assign is this System.Collections.Generic.List1[System.String]. Doing to ToString on a List just gives you the the type of list it is. It doesnt join all your characters back up. Thats probably the main thing that is casuing you issues.
Also you are forcing everything into string types and really you don't need to a lot of the time, because string already implements IEnumerable you can get your string as a list of chars by just doing myString.ToList()
So there is no need for this:
foreach (char item in input)
{
remaining.Add(item.ToString());
}
things like string.Contains have overloads that take chars so again no need for making things string here:
foreach (char letter in word)
{
string c = letter.ToString();
if (input.Contains(c))
{
letters++;
remaining.Remove(c);
input = remaining.ToString();
}
}
you can just user the letter variable of type char and pass that into contains and beacuse remaining is now a List<char> you can remove a char from it.
again Don't reassign remaining.ToString() back into input. use string.Join like this
string.Join(string.empty,remaining);
As someone else has posted there is a probably better ways of doing this, but I hope that what I've put here helps you understand what was going wrong and will help you learn
You can also use Regular Expression which was created for such scenarios.
bool IsMatch(string input, string word)
{
var pattern = string.Format("\\b[{0}]+\\b", input);
var r = new Regex(pattern);
return r.IsMatch(word);
}
I created a sample code for you on DotNetFiddle.
You can check what the pattern does at Regex101. It has a pretty "Explanation" and "Quick Reference" panel.
There are a lot of ways to achieve that, here is a suggestion:
static void Main(string[] args)
{
Func("cacten","ace");
Func("cacten", "aced");
Console.ReadLine();
}
static void Func(string input, string word)
{
bool isMatch = true;
foreach (Char s in word)
{
if (!input.Contains(s.ToString()))
{
isMatch = false;
break;
}
}
// success
if (isMatch)
{
Console.WriteLine(word);
}
// no match
else
{
Console.WriteLine("No Match");
}
}
Not really an answer to your question but its always fun to do this sort of thing with Linq:
static void Print(string input, string word)
{
if (word.All(ch => input.Contains(ch) &&
word.GroupBy(c => c)
.All(g => g.Count() <= input.Count(c => c == g.Key))))
Console.WriteLine(word);
}
Functional programming is all about what you want without all the pesky loops, ifs and what nots... Notice that this code does what you'd do in your head without needing to painfully specify step by step how you'd actually do it:
Make sure all characters in word are in input.
Make sure all characters in word are used at most as many times as they are present in input.
Still, getting the basics right is a must, posted this answer as additional info.

replacing text with cleaned word case insensitive c#

I have a list of bad words, that if found in the text string, will be replaced by a cleaned word.
eg. badwords{woof} is replaced by w$$f
But is currently only working when the array list is in the same case as the matched word in the sentence.
var badWords = new List<string>{"woof", "meow"}
var string = "I have a cat named meow and a dog name Woof."
Should become === "I have a cat named m$$w and a dog name W$$f"
public string CensorText(string text)
{
if (string.IsNullOrWhiteSpace(text))
{
return text;
}
foreach (string word in CensoredWords)
{
text = text.Replace(word, WordCleaner(word));
}
return text;
}
private static string WordCleaner(string wordToClean)
{
string firstChar = wordToClean.Substring(0,1);
string lastChar = wordToClean.Substring(wordToClean.Length - 1);
string centerHash = new string('$', wordToClean.Length-2);
return string.Concat(firstChar, centerHash, lastChar);
}
How can make it so that its case insensitive when looping through the words and cleaning them. Simpler the answer is better.
Try replacing:
text = text.Replace(word, WordCleaner(word));
with
text = text.Replace(word.ToLower(), WordCleaner(word));
This converts any upper case letter to a lower case one.
Edit
I've realised that I've made the wrong variable into lower case.
Change:
public string CensorText(string text)
{
To:
public string CensorText(string text)
{
text = text.ToLower();
Edit 2
To retain the original sentence with the censored words changed, it would be much easier to use re instead. First, revert your file back to how it was in the question.
Now replace:
text = text.Replace(word, WordCleaner(word));
with:
text = regex.replace(text,word,WordCleaner(word),RegexOptions.Ignorecase);
Here's a simple option you can use.
The benefit is you don't care which of the word is lower case, it'll work for either cases. Note that compare returns an int, hence why we check it's 0 for a match.
string input = "the Woof is on Fire, we don't need no bucket, leT the ...";
string[] bad_words = new string[] {"woof","fire","BucKet", "Let"};
foreach (var word in input.Split(' ')) {
if (bad_words.Any( b => String.Compare( word, b // Following line does what you want:
, StringComparison.OrdinalIgnoreCase) == 0))
Console.Write(WordCleaner(word));
else
Console.Write(word);
}
Output:
the W$$f is on F$$e we don't need no b$$$$t l$T the ...
Seems fine to me. Note that if you split on space, a word with a comma right after will have that comma as part of the word

How can you put single spaces into a string of characters in C#

I am still a beginner in C# and I know there is a method that can be used to do this but I can't seem to find it online.
I have a function that permutates a word
static void Main(string[] args)
{
string[] list = "a b c d".Split();
foreach (string[] permutation in Permutations<string>.AllFor(list))
{
System.Console.WriteLine(string.Join(" ", permutation));
}
}
However it only works with words that are broken up. (eg. "a b c d" ) Since that is not really a practical way to ask a user for input, I want to find a way to take a word from the user (an unbroken word like "hello" ) and break it up for the function to understand. Eg. form the input word of the use "happy" to a spaced word for the program to understand = "h a p p y"
I tried this code:
//splits the word into an array
string[] arr = name.Split();
//splits the array with spaces to enter into the program
name = string.Join(" ",arr);
arr = name.Split();
But it just ends up coming out unbroken anyway. Can someone tell me the easiest way to do this?
Just to mention I am still a beginner in C# and programming in total I might not understand some of the higher level concepts. I have been through some answers on this website and I have seen some answers that I don't understand at all.
You can loop over the string to convert it to an array, and then use Join.
using System.Text.RegularExpressions;
using System;
public class Program{
public static void Main(string[] args) {
string v = "hello";
// Convert into the a string array, the old-fashioned way.
string[] name = new string[v.Length];
for (int i = 0; i < v.Length; i++)
name[i] = v[i] + "";
string feedToPermutationFunction = string.Join(" ",name));
// Feed the above string into your permutation code.
}
}
You just need to separate each character and then concatenate them with a space:
This is the simplest way:
var userInput = Console.ReadLine();
var output = string.Join<char>(" ", userInput);
Console.WriteLine(output);
char[] array=input.ToArray();
string val="";
for(int i=0;i<array.Length;i++)
{
val+=array[i]+" ";
}
this will give you a string with spaces like you wanted Val
create an array with the string length
string[] strarray=new string[val.Length];
for(int i=0;i<strarray.Length;i++)
{
strarray[i]=val.Substring(i,len); //**i** is for string index,,,**len** string length in each index
}

Finding the number of occurences strings in a specific format occur in a given text

I have a large string, where there can be specific words (text followed by a single colon, like "test:") occurring more than once. For example, like this:
word:
TEST:
word:
TEST:
TEST: // random text
"word" occurs twice and "TEST" occurs thrice, but the amount can be variable. Also, these words don't have to be in the same order and there can be more text in the same line as the word (as shown in the last example of "TEST"). What I need to do is append the occurrence number to each word, for example the output string needs to be this:
word_ONE:
TEST_ONE:
word_TWO:
TEST_TWO:
TEST_THREE: // random text
The RegEx for getting these words which I've written is ^\b[A-Za-z0-9_]{4,}\b:. However, I don't know how to accomplish the above in a fast way. Any ideas?
Regex is perfect for this job - using Replace with a match evaluator:
This example is not tested nor compiled:
public class Fix
{
public static String Execute(string largeText)
{
return Regex.Replace(largeText, "^(\w{4,}):", new Fix().Evaluator);
}
private Dictionary<String, int> counters = new Dictionary<String, int>();
private static String[] numbers = {"ONE", "TWO", "THREE",...};
public String Evaluator(Match m)
{
String word = m.Groups[1].Value;
int count;
if (!counters.TryGetValue(word, out count))
count = 0;
count++;
counters[word] = count;
return word + "_" + numbers[count-1] + ":";
}
}
This should return what you requested when calling:
result = Fix.Execute(largeText);
i think you can do this with Regax.Replace(string, string, MatchEvaluator) and a dictionary.
Dictionary<string, int> wordCount=new Dictionary<string,int>();
string AppendIndex(Match m)
{
string matchedString = m.ToString();
if(wordCount.Contains(matchedString))
wordCount[matchedString]=wordCount[matchedString]+1;
else
wordCount.Add(matchedString, 1);
return matchedString + "_"+ wordCount.ToString();// in the format: word_1, word_2
}
string inputText = "....";
string regexText = #"";
static void Main()
{
string text = "....";
string result = Regex.Replace(text, #"^\b[A-Za-z0-9_]{4,}\b:",
new MatchEvaluator(AppendIndex));
}
see this:
http://msdn.microsoft.com/en-US/library/cft8645c(v=VS.80).aspx
If I understand you correctly, regex is not necessary here.
You can split your large string by the ':' character. Maybe you also need to read line by line (split by '\n'). After that you just create a dictionary (IDictionary<string, int>), which counts the occurrences of certain words. Every time you find word x, you increase the counter in the dictionary.
EDIT
Read your file line by line OR split the string by '\n'
Check if your delimiter is present. Either by splitting by ':' OR using regex.
Get the first item from the split array OR the first match of your regex.
Use a dictionary to count your occurrences.
if (dictionary.Contains(key)) dictionary[key]++;
else dictionary.Add(key, 1);
If you need words instead of numbers, then create another dictionary for these. So that dictionary[key] equals one if key equals 1. Mabye there is another solution for that.
Look at this example (I know it's not perfect and not so nice)
lets leave the exact argument for the Split function, I think it can help
static void Main(string[] args)
{
string a = "word:word:test:-1+234=567:test:test:";
string[] tks = a.Split(':');
Regex re = new Regex(#"^\b[A-Za-z0-9_]{4,}\b");
var res = from x in tks
where re.Matches(x).Count > 0
select x + DecodeNO(tks.Count(y=>y.Equals(x)));
foreach (var item in res)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
private static string DecodeNO(int n)
{
switch (n)
{
case 1:
return "_one";
case 2:
return "_two";
case 3:
return "_three";
}
return "";
}

Categories