Manipulating String in C# - c#

I have a code in C# and have to print a label with the name of the seller, but i have a problem.
Every line in the label comport 20 letters and i have 2 lines to put this name.
I need to arrange the name of the seller in the 2 lines, without cut words.
For example - Name: JOSE MAURICIO BERTOLOTO MENDES
Line1: JOSE MAURICIO
Line2: BERTOLOTO MENDES
someone know how i do this?
Thanks
EDIT: Based in the answers, i implemente this code:
string[] SellerPrint = Seller.Split(' ');
Line1 = "";
Line2 = "";
foreach (string name in SellerPrint )
{
if (Line1.Length <= 20)
{
if ((Line1 + name).Length <= 20)
Line1 += (Line1.Length == 0) ? name : " " + name;
else
break;
}
}
Line2 = (Seller.Replace(Line1, "").Length <= 20) ? Seller.Replace(Line1+ " ", "") : Seller.Replace(Line1+ " ", "").Remove(20);
Thanks for the help!

You could simply split the string into words using string.Split() and then add to each as long it small enough to add to the line.
I also wouldn't use the character count but use Graphics.MeasureString() instead.

You can split the full name in to it's individual parts.
var names = fullname.Split(' ');
Which will give you a string[]. From there you can do the math by looking at length of each string.

The idea is that you want to append all parts of the name until you will reach or exceed your 20 character limit on the next token. When that happens, append a new line with that token and continue appending until you hit the character limit once again.
Here is a quick example:
public static string FormatName(string name)
{
const int MaxLength = 20;
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
if (name.Length <= MaxLength)
return name;
string[] tokens = name.Split(' ');
if (tokens.Length == 0)
return name; //hyphen the name?
StringBuilder sb = new StringBuilder(name.Length);
int len = 0;
foreach (string token in tokens)
{
if (token.Length + len < MaxLength)
{
sb.Append(token + " ");
len += token.Length;
}
else
{
sb.Append(Environment.NewLine + token + " ");
len = 0;
}
}
return sb.ToString();
}
Note: I left the case open for when a section of the name, without spaces, is longer than 20 characters. Also, this example will continue on to the Nth line, if the name won't fit onto two lines.

Here is the logic.
Use String.split to split the name into an array. Iterate over the strings in the array, concat them into a line, while the line is less than 20 characters. A recursive function would be a good idea! When you are greater than two lines, drop the rest of the names that put it over.

I'm not sure but I think you can use a special character: '\n' (without the quotes)
Its basiclly stands for new line. So for example : JOSE MAURICIO BERTOLOTO MENDES will become JOSE MAURICIO \n BERTOLOTO MENDES.

Related

Reverse Words at odd position only C#

This is my code. How can I edit it to show every word which is at the odd position ONLY to be reversed?
for (int i = input.Length - 1; i >= 0; i--)
{
if (input[i] == ' ')
{
result = tmp + " " + result;
tmp = "";
}
else
tmp += input[i];
}
result = tmp + " " + result;
Console.WriteLine(result);
Example input:
"How are you today"
to output:
"How era you yadot"
Based on the position of a word ['How' -> 0] do not reverse; [are -> 1 odd index] Reverse
You can achieve it with the help of LINQ:
var input = "hello this is a test message";
var inputWords = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var result = string.Join(" ",
inputWords.Select((w, i) =>
i % 2 == 0
? w
: new string(w.Reverse().ToArray())
));
Where w in the select is the word, and i is the index, starting at 0 for the first word. % is the modulus operator and gets the remainder. If i % 2 == 0 (i.e. i can be divided by 2 with no remainder), then the original is returned. If there is a remainder (odd) then the reversed word is returned. Finally, it's all wrapped up in a string.Join(" ", items); which turns it back into a normal string rather than an array of items.
Try it online
So far you have a string, like this:
string input = "I want to reverse all odd words (odd words only!).";
And you, naturally, want to perform the task. Now it's the main question what's an odd word?
If you mean word's position (I at position 0, want at 1 - should be reversed etc.)
then you can use regular expressions to match words and Linq to process them:
using System.Linq; // To reverse single word
using System.Text.RegularExpressions; // To match the words within the text
...
// Let's elaborate the test example: add
// 1. some punctuation - ()!. - to preserve it
// 2. different white spaces (spaces and tabulation - \t)
// to add difficulties for naive algorithms
// 3. double spaces (after "to") to mislead split based algorithms
string input = "I want to reverse all\todd words (odd words only!).";
int index = 0; // words' indexes start from zero
string result = Regex.Replace(
input,
"[A-Za-z']+", // word is letters and apostrophes
match => index++ % 2 == 0
? match.Value // Even words intact
: string.Concat(match.Value.Reverse())); // Odd words reversed
Console.WriteLine(result);
If you want to reverse the words with odd Length, i.e. I, all, odd then all you have to do is to change the condition to
match => match.Value % 2 == 0
Outcome:
I tnaw to esrever all ddo words (ddo words ylno!).
Please, notice, that the punctuation has been preserved (only words are reversed).
OP: Based on the position of a word ['How' -> 0] do not reverse; [are -> 1 odd index] Reverse
public static void Main()
{
string input = "How are you today Laken-C";
//As pointed out by #Dmitry Bychenko string input = "How are you today";
//(double space after How) leads to How are uoy today outcome
input = Regex.Replace(input, #"\s+", " ");
var inp = input.Split(' ').ToList();
for (int j = 0; j < inp.Count(); j++)
{
if(j % 2 == 1)
{
Console.Write(inp[j].Reverse().ToArray());
Console.Write(" ");
}
else
Console.Write(inp[j] + " ");
}
}
OUTPUT:
DEMO:
dotNetFiddle
try this is perfect working code..
static void Main(string[] args)
{
string orgstr = "my name is sagar";
string revstr = "";
foreach (var word in orgstr.Split(' '))
{
string temp = "";
foreach (var ch in word.ToCharArray())
{
temp = ch + temp;
}
revstr = revstr + temp + " ";
}
Console.Write(revstr);
Console.ReadKey();
}
Output: ym eman si ragas

C# need to get fragment from Text

Hi I need to find longest sequence of words in text that's matching condition: if word is ending with letter N other word should start with letter N. N - could be any letter. For Example:
Simple Elephant
Apple Strong
So first line is matching my mentioned condition so I need to print it out to console.
Failing to think of an algorithm how this should work.
I make this code for you. Can answer to your questions.
List<string> sentenses = new List<string>();
sentenses.Add("hi, my name is Sam.");
sentenses.Add("Hi,is,settled,drums.");
sentenses.Add("Add all your sentenses here");
string longestSentense ="";
int longestCount = 0;
foreach(string sentense in sentenses)
{
string[] words = Regex.Split(sentense, "[^a-zA-Z]"); // cut sentense by all not letter character
int count = 0;
for (int i=0;i<words.Length-1;i++)
{
// check if last letter of words[i] is the same letter as the first or words[i+1]
if(words[i].Equals("") || words[i+1].Equals("")) continue; // don't look to "empty word"
if (words[i][words[i].Length-1].Equals(words[i + 1][0])) count++;
}
// if here is the biggest number of matching words, we save it
if(count>longestCount)
{
longestCount = count;
longestSentense = sentense;
}
}
Console.WriteLine("The sentence that contains the most of matching words : \n"
+ longestSentense + "\n"
+ " with " + longestCount + " junctions between matching words.");
Console.ReadKey();

Iterating backwards through an char array after finding a known word

I've got a project I'm working on in C#. I've got two char array's. One is a sentence and one is a word. I've got to iterate through the sentence array until I find a word that matches the word that was turned into an word array what I'm wondering is once I find the word how do I iterate backwards through the sentence array at the point I found the word back through the same length as the word array?
Code :
String wordString = "(Four)";
String sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
char[] wordArray = wordString.ToCharArray();
List<String> words = sentenceString.Split(' ').ToList<string>();
//This would be the part where I iterate through sentence
foreach (string sentence in sentArray)
{
//Here I would need to find where the string of (Four) and trim it and see if it equals the wordString.
if (sentence.Contains(wordString)
{
//At this point I would need to go back the length of wordString which happens to be four places but I'm not sure how to do this. And for each word I go back in the sentence I need to capture that in another string array.
}
I don't know if I'm being clear enough on this but if I'm not please feel free to ask.. Thank you in advanced. Also what this should return is "fowl of Uruguay repeaters". So basically the use case is for the number of letters in the parenthesis the logic should return the same number of words before the word in parenthesis.
our are you. I have few question concerned to this exercise.
If the Word (four) was in beginning it should not return? or return all string?
As the length of four is equal to 4 imagine if that word appear as the second word on sentence what it should return just the first word or return 4 words even including the (four) word.?
My solution is the laziest one I just see your question and decide to help.
My solution assumes it return all the word before the (four) if the length is bigger than the word before the (four) word.
My solution return empty string if the word (four) is in the beginning.
My solution return Length of (four) (4) words before (four) word.
ONCE AGAIN IT IS NOT MY BEST APPROACH.
I see the code bellow:
string wordString = "(Four)";
string sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
//Additionally you can add splitoption to remove the empty word on split function bellow
//Just in case there are more space in sentence.
string[] splitedword = sentenceString.Split(' ');
int tempBackposition = 0;
int finalposition = 0;
for (int i = 0; i < splitedword.Length; i++)
{
if (splitedword[i].Contains(wordString))
{
finalposition = i;
break;
}
}
tempBackposition = finalposition - wordString.Replace("(","").Replace(")","").Length;
string output = "";
tempBackposition= tempBackposition<0?0:tempBackposition;
for (int i = tempBackposition; i < finalposition; i++)
{
output += splitedword[i] + " ";
}
Console.WriteLine(output);
Console.ReadLine();
If it's not what you want can you answer my questions on top? or help me to understand were it's wrong
int i ;
string outputString = (i=sentenceString.IndexOf(wordString))<0 ?
sentenceString : sentenceString.Substring(0,i) ;
var wordString = "(Four)";
int wordStringInt = 4; // Just do switch case to convert your string to int
var sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
var sentenceStringArray = sentenceString.Split(' ').ToList();
int wordStringIndexInArray = sentenceStringArray.IndexOf(wordString) - 1;
var stringOutPut = "";
if (wordStringIndexInArray > 0 && wordStringIndexInArray > wordStringInt)
{
stringOutPut = "";
while (wordStringInt > 0)
{
stringOutPut = sentenceStringArray[wordStringInt] + " " + stringOutPut;
wordStringInt--;
}
}
What you are matching is kind of complex, so for a more general solution you could use regular expressions.
First we declare what we are searching for:
string word = "(Four)";
string sentence = "Maybe the fowl of Uruguay repeaters (Four) will be found";
We will then search for the words in this string using regular expressions. Since we don't want to match whitespace, and we need to know where each match actually starts and we need to know the word inside the parenthesis we tell it that we optionally want opening and ending parenthesis, but we also want the contents of those as a match:
var words = Regex.Matches(sentence, #"[\p{Ps}]*(?<Content>[\w]+)[\p{Pe}]*").Cast<Match>().ToList();
[\p{Ps}] means we want opening punctuation ([{ etc. while the * indicates zero or more.
Followed is a sub-capture called Content (specified by ?<Content>) with one or more word characters.
At the end we specify that we want zero or more ending punctuation.
We then need to find the word in the list of matches:
var item = words.Single(x => x.Value == word);
Then we need to find this item's index:
int index = words.IndexOf(item);
At this point we just need to know the length of the contents:
var length = item.Groups["Content"].Length;
This length we use to go back in the string 4 words
var start = words.Skip(index - length).First();
And now we have everything we need:
var result = sentence.Substring(start.Index, item.Index - start.Index);
Result should contain fowl of Uruguay repeaters.
edit: It may be a lot simpler to just figure out the count from the word rather than from the content. In that case the complete code should be the following:
string word = "(Four)";
string sentence = "Maybe the fowl of Uruguay repeaters (Four) will be found";
var wordMatch = Regex.Match(word, #"[\p{Ps}]*(?<Content>[\w]+)[\p{Pe}]*");
var length = wordMatch.Groups["Content"].Length;
var words = Regex.Matches(sentence, #"\S+").Cast<Match>().ToList();
var item = words.Single(x => x.Value == word);
int index = words.IndexOf(item);
var start = words.Skip(index - length).First();
var result = sentence.Substring(start.Index, item.Index - start.Index);
\S+ in this case means "match one or more non-whitespace character".
You should try something like the following, which uses Array.Copy after it finds the number word. You will still have to implement the ConvertToNum function correctly (it is hardcoded in for now), but this should be a quick and easy solution.
string[] GetWords()
{
string sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
string[] words = sentenceString.Split();
int num = 0;
int i; // scope of i should remain outside the for loop
for (i = 0; i < words.Length; i++)
{
string word = words[i];
if (word.StartsWith("(") && word.EndsWith(")"))
{
num = ConvertToNum(word.Substring(1, word.Length - 1));
// converted the number word we found, so we break
break;
}
}
if (num == 0)
{
// no number word was found in the string - return empty array
return new string[0];
}
// do some extra checking if number word exceeds number of previous words
int startIndex = i - num;
// if it does - just start from index 0
startIndex = startIndex < 0 ? 0 : startIndex;
int length = i - startIndex;
string[] output = new string[length];
Array.Copy(words, startIndex, output, 0, length);
return output;
}
// Convert the number word to an integer
int ConvertToNum(string numberStr)
{
return 4; // you should implement this method correctly
}
See - Convert words (string) to Int, for help implementing the ConvertToNum solution. Obviously it could be simplified depending on the range of numbers you expect to deal with.
Here is my solution, im not using regex at all, for the sake of easy understanding:
static void Main() {
var wordString = "(Four)";
int wordStringLength = wordString.Replace("(","").Replace(")","").Length;
//4, because i'm assuming '(' and ')' doesn't count.
var sentenceString = "Maybe the fowl of Uruguay repeaters (Four) will be found";
//Transform into a list of words, ToList() to future use of IndexOf Method
var sentenceStringWords = sentenceString.Split(' ').ToList();
//Find the index of the word in the list of words
int wordIndex = sentenceStringWords.IndexOf(wordString);
//Get a subrange from the original list of words, going back x Times the legnth of word (in this case 4),
var wordsToConcat = sentenceStringWords.GetRange(wordIndex-wordStringLength, wordStringLength);
//Finally concat the output;
var outPut = string.Join(" ", wordsToConcat);
//Output: fowl of Uruguay repeaters
}
I have a solution for you:
string wordToMatch = "(Four)";
string sentence = "Maybe the fowl of Uruguay repeaters (Four) will be found";
if (sentence.Contains(wordToMatch))
{
int length = wordToMatch.Trim(new[] { '(', ')' }).Length;
int indexOfMatchedWord = sentence.IndexOf(wordToMatch);
string subString1 = sentence.Substring(0, indexOfMatchedWord);
string[] words = subString1.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var reversed = words.Reverse().Take(length);
string result = string.Join(" ", reversed.Reverse());
Console.WriteLine(result);
Console.ReadLine();
}
Likely this can be improved regardng performance, but I have a feeling you don't care about that. Make sure you are using 'System.Linq'
I assumed empty returns when input is incomplete, feel free to correct me on that. Wasn't 100% clear in your post how this should be handled.
private string getPartialSentence(string sentence, string word)
{
if (string.IsNullOrEmpty(sentence) || string.IsNullOrEmpty(word))
return string.Empty;
int locationInSentence = sentence.IndexOf(word, StringComparison.Ordinal);
if (locationInSentence == -1)
return string.Empty;
string partialSentence = sentence.Substring(0, locationInSentence);
string[] words = partialSentence.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
int nbWordsRequired = word.Replace("(", "").Replace(")", "").Length;
if (words.Count() >= nbWordsRequired)
return String.Join(" ", words.Skip(words.Count() - nbWordsRequired));
return String.Join(" ", words);
}
I went with using an enumeration and associated dictionary to pair the "(Four)" type strings with their integer values. You could just as easily (and maybe easier) go with a switch statement using
case "(Four)": { currentNumber = 4; };
I feel like the enum allows a little more flexibility though.
public enum NumberVerb
{
one = 1,
two = 2,
three = 3,
four = 4,
five = 5,
six = 6,
seven = 7,
eight = 8,
nine = 9,
ten = 10,
};
public static Dictionary<string, NumberVerb> m_Dictionary
{
get
{
Dictionary<string, NumberVerb> temp = new Dictionary<string, NumberVerb>();
temp.Add("(one)", NumberVerb.one);
temp.Add("(two)", NumberVerb.two);
temp.Add("(three)", NumberVerb.three);
temp.Add("(four)", NumberVerb.four);
temp.Add("(five)", NumberVerb.five);
temp.Add("(six)", NumberVerb.six);
temp.Add("(seven)", NumberVerb.seven);
temp.Add("(eight)", NumberVerb.eight);
temp.Add("(nine)", NumberVerb.nine);
temp.Add("(ten)", NumberVerb.ten);
return temp;
}
}
static void Main(string[] args)
{
string resultPhrase = "";
// Get the sentance that will be searched.
Console.WriteLine("Please enter the starting sentance:");
Console.WriteLine("(don't forget your keyword: ie '(Four)')");
string sentance = Console.ReadLine();
// Get the search word.
Console.WriteLine("Please enter the search keyword:");
string keyword = Console.ReadLine();
// Set the associated number of words to backwards-iterate.
int currentNumber = -1;
try
{
currentNumber = (int)m_Dictionary[keyword.ToLower()];
}
catch(KeyNotFoundException ex)
{
Console.WriteLine("The provided keyword was not found in the dictionary.");
}
// Search the sentance string for the keyword, and get the starting index.
Console.WriteLine("Searching for phrase...");
string[] words = sentance.Split(' ');
int searchResultIndex = -1;
for (int i = 0; (searchResultIndex == -1 && i < words.Length); i++)
{
if (words[i].Equals(keyword))
{
searchResultIndex = i;
}
}
// Handle the search results.
if (searchResultIndex == -1)
{
resultPhrase = "The keyword was not found.";
}
else if (searchResultIndex < currentNumber)
{
// Check the array boundaries with the given indexes.
resultPhrase = "Error: Out of bounds!";
}
else
{
// Get the preceding words.
for (int i = 0; i < currentNumber; i++)
{
resultPhrase = string.Format(" {0}{1}", words[searchResultIndex - 1 - i], resultPhrase);
}
}
// Display the preceding words.
Console.WriteLine(resultPhrase.Trim());
// Exit.
Console.ReadLine();
}

Add to string until hits length (noobie C# guy)

I am trying to read a text file, break it into a string array, and then compile new strings out of the words, but I don't want it to exceed 120 characters in length.
What I am doing with is making it write PML to create a macro for some software I use, and the text can't exceed 120 characters. To take it even further I need to wrap the 120 characters or less (to the nearest word), string with "BTEXT |the string here|" which is the command.
Here is the code:
static void Main(string[] args)
{
int BIGSTRINGLEN = 120;
string readit = File.ReadAllText("C:\\stringtest.txt");
string finish = readit.Replace("\r\n", " ").Replace("\t", "");
string[] seeit = finish.Split(' ');
StringBuilder builder = new StringBuilder(BIGSTRINGLEN);
foreach(string word in seeit)
{
while (builder.Length + " " + word.Length <= BIGSTRINGLEN)
{
builder.Append(word)
}
}
}
Try using an if instead of the while as you will continually append the same word if not!!
Rather than read the entire file into memory, you can read it a line at a time. That will reduce your memory requirements and also prevent you having to replace the newlines.
StringBuilder builder = new StringBuilder(BIGSTRINGLEN);
foreach (var line in File.ReadLines(filename))
{
// clean up the line.
// Do you really want to replace tabs with nothing?
// if you want to treat tabs like spaces, change the call to Split
// and include '\t' in the character array.
string finish = line.Replace("\t", string.Empty);
string[] seeit = finish.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
foreach (string word in seeit)
{
if ((builder.Length + word.Length + 1 <= BIGSTRINGLEN)
{
if (builder.Length != 0)
builder.Append(' ');
builder.Append(word);
}
else
{
// output line
Console.WriteLine(builder.ToString());
// and reset the builder
builder.Length = 0;
}
}
}
// and write the last line
if (builder.Length > 0)
Console.WriteLine(builder.ToString());
That code is going to fail if a word is longer than BIGSTRINGLEN. Long words will end up outputting a blank line. I think you can figure out how to handle that case if it becomes a problem.
Matthew Moon is right - your while loop is not going to work as currently placed.
But that aside, you have some problems in this line
while (builder.Length + " " + word.Length <= BIGSTRINGLEN)
builder.Length and word.Length are integers - the number of characters in each word. " " is not an integer, it's a string. You can't correctly add 10 + " " + 5. You probably want
while (builder.Length + (" ").Length + word.Length <= BIGSTRINGLEN)
// or
while (builder.Length + 1 + word.Length <= BIGSTRINGLEN)

How to split long strings into fixed array items

I have a dictionary object IDictionary<string, string> which only has the following items:
Item1, Items2 and Item3. Each item only has a maximum length of 50 characters.
I then have a list of words List<string>. I need a loop that will go through the words and add them to the dictionary starting at Item1, but before adding it to the dictionary the length needs to be checked. If the new item and the current item's length added together is greater than 50 characters then the word needs to move down to the next line (in this case Item2).
What is the best way to do this?
I'm not sure why this question got voted down so much, but perhaps the reason is you have a very clear algorithm already, so it should be trivial to get the C# code. As it stands, either you're either really inexperienced or really lazy. I'm going to assume the former.
Anyways, lets walk through the requirements.
1) "I then have a list of words List." you have this line in some form already.
List<string> words = GetListOfWords();
2) "go through the words and add them to the dictionary starting at Item1" -- I'd recommend a List instead of a dictionary, if you're going for a sequence of strings. Also, you'll need a temporary variable to store the contents of the current line, because you're really after adding a full line at a time.
var lines = new List<string>();
string currentLine = "";
3) "I need a loop that will go through the words"
foreach(var word in words) {
4) " If the new item and the current item's length added together is greater than 50 characters" -- +1 for the space.
if (currentLine.Length + word.Length + 1 > 50) {
5) "then the word needs to move down to the next line "
lines.Add(currentLine);
currentLine = word;
}
6) " go through the words and add them to the dictionary starting at Item1 " -- you didn't phrase this very clearly. What you meant was you want to join each word to the last line unless it would make the line exceed 50 characters.
else {
currentLine += " " + word;
}
}
lines.Add(currentLine); // the last unfinished line
and there you go.
If you absolutely need it as an IDictionary with 3 lines, just do
var dict = new Dictionary<string,string>();
for(int lineNum = 0; lineNum < 3; lineNum ++)
dict["Address"+lineNum] = lineNume < lines.Length ? lines[lineNum] : "";
I currently have this and was wondering if there was perhaps a better solution:
public IDictionary AddWordsToDictionary(IList words)
{
IDictionary addressParts = new Dictionary();
addressParts.Add("Address1", string.Empty);
addressParts.Add("Address2", string.Empty);
addressParts.Add("Address3", string.Empty);
int currentIndex = 1;
foreach (string word in words)
{
if (!string.IsNullOrEmpty(word))
{
string key = string.Concat("Address", currentIndex);
int space = 0;
string spaceChar = string.Empty;
if (!string.IsNullOrEmpty(addressParts[key]))
{
space = 1;
spaceChar = " ";
}
if (word.Length + space + addressParts[key].Length > MaxAddressLineLength)
{
currentIndex++;
key = string.Concat("Address", currentIndex);
space = 0;
spaceChar = string.Empty;
if (currentIndex > addressParts.Count)
{
break; // To big for all 3 elements so discard
}
}
addressParts[key] = string.Concat(addressParts[key], spaceChar, word);
}
}
return addressParts;
}
I would just do the following and do what you like with the resulting "lines"
static List<string> BuildLines(List<string> words, int lineLen)
{
List<string> lines = new List<string>();
string line = string.Empty;
foreach (string word in words)
{
if (string.IsNullOrEmpty(word)) continue;
if (line.Length + word.Length + 1 <= lineLen)
{
line += " " + word;
}
else
{
lines.Add(line);
line = word;
}
}
lines.Add(line);
return lines;
}

Categories