PigLatin Translator Crashing C# - c#

For some reason when I run this code I am noticing that the letter "I or i" or word "it" crashes the program. Also when I just click translate with nothing entered it crashes as well. I have gone over this code over and over but I can't find the problem. Any suggestions?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void btnTranslate_Click(object sender, EventArgs e)
{
String input = Convert.ToString(txtInput.Text.Trim());
String inputTr = Regex.Replace(input, " {2,}", " ");
String pigLatin = "";
String temp = "";
String restOfWord = "";
String vowels = "AEIOUaeiou";
String consonants = "YBCDFGHJKLMNPQRSTVXWZbcdfghjklmnpqrstvxwzy";
string[] words = inputTr.Split();
foreach (string word in words)
{
if (string.IsNullOrEmpty(txtInput.Text))
{
MessageBox.Show("Text must be entered");
}
int index = word.IndexOfAny(new char[] { 'A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o', 'u' });
if (Regex.IsMatch(word, "[##$%0-9]"))
{
pigLatin += word + " ";
}
else if (!(char.IsPunctuation(word.Last())) && vowels.Contains(word[0]) && word.Contains(word.Substring(1, 2).ToLower()))
{
pigLatin += word + "way" + " ";
}
else if (char.IsPunctuation(word.Last()) && vowels.Contains(word[0]) && word.Contains(word.Substring(1, 2).ToLower()))
{
pigLatin += word.Substring(0, word.Length - 1) + "way" + word.Last() + " ";
}
else if (!(char.IsPunctuation(word.Last())) && consonants.Contains(word[0]) && word.StartsWith(word.Substring(0, 1).ToLower()))
{
string firstPart = word.Substring(0, index);
restOfWord = word.Substring(index, word.Length - index);
pigLatin += restOfWord + firstPart + "ay" + " ";
}
else if (char.IsPunctuation(word.Last()) && consonants.Contains(word[0]) && word.StartsWith(word.Substring(0, 1).ToLower()))
{
string firstPart = word.Substring(0, index);
restOfWord = word.Substring(index, word.Length - index);
pigLatin += restOfWord.Substring(0, restOfWord.Length - 1) + firstPart + "ay" + restOfWord.Last() + " ";
}
else if (!(char.IsPunctuation(word.Last())) && word.Contains(word.ToUpper()) && vowels.Contains(word.Substring(0, 1).ToUpper()))
{
pigLatin += word + "WAY" + " ";
}
else if (char.IsPunctuation(word.Last()) && word.Contains(word.ToUpper()) && vowels.Contains(word.Substring(0, 1).ToUpper()))
{
pigLatin += word.Substring(0, word.Length - 1) + "WAY" + word.Last() + " ";
}
else if (!(char.IsPunctuation(word.Last())) && word.StartsWith(word.Substring(0, 1).ToUpper()) && consonants.Contains(word.Substring(0, 1).ToUpper()) && word.Contains(word.Substring(1, 2).ToLower()))
{
string firstPart = word.Substring(0, index);
restOfWord = word.Substring(index, word.Length - index);
pigLatin += restOfWord.Substring(0, 1).ToUpper() + restOfWord.Substring(1, restOfWord.Length - 1).ToLower() + firstPart.ToLower() + "ay" + " ";
}
else if (char.IsPunctuation(word.Last()) && word.StartsWith(word.Substring(0, 1).ToUpper()) && consonants.Contains(word.Substring(0, 1).ToUpper()) && word.Contains(word.Substring(1, 2).ToLower()))
{
string firstPart = word.Substring(0, index);
restOfWord = word.Substring(index, word.Length - index);
temp = restOfWord.Substring(0, 1).ToUpper() + restOfWord.Substring(0, restOfWord.Length - 1).ToLower() + firstPart.ToLower() + "ay" + restOfWord.Last() + " ";
temp = temp.Remove(0, 1);
pigLatin += temp.Substring(0, 1).ToUpper() + temp.Substring(1, temp.Length - 1).ToLower() + " ";
}
else if (!(char.IsPunctuation(word.Last())) && word.Contains(word.ToUpper()) && consonants.Contains(word.Substring(0, 1).ToUpper()))
{
string firstPart = word.Substring(0, index);
restOfWord = word.Substring(index, word.Length - index);
pigLatin += restOfWord.ToUpper() + firstPart.ToUpper() + "AY" + " ";
}
else if (char.IsPunctuation(word.Last()) && word.Contains(word.ToUpper()) && consonants.Contains(word.Substring(0, 1).ToUpper()))
{
string firstPart = word.Substring(0, index);
restOfWord = word.Substring(index, word.Length - index);
pigLatin += restOfWord.Substring(0, restOfWord.Length - 1).ToUpper() + firstPart.ToUpper() + "AY" + word.Last() + " ";
}
txtOutput.Text = pigLatin;
}
}
private void btnClear_Click(object sender, EventArgs e)
{
txtInput.Text = "";
txtOutput.Text = "";
txtInput.Focus();
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
private void txtInput_TextChanged(object sender, EventArgs e)
{
}
}

In several places throughout your code you have "Substring(1, 2)" - if the word you are currently processing is short than three characters long then you will get an exception because you are trying to get a substring that extends beyond the end of the string.
You need to add length checking into your code.
e.g.
...
...
else if (!(char.IsPunctuation(word.Last())) && vowels.Contains(word[0]) &&
&& (word.Length >= 3) && word.Contains(word.Substring(1, 2).ToLower()))
...
...
Just as a note on debugging - you could put a (conditional) breakpoint on the line where the exception occurs & then check each individual part of your if statement in the Immediate Window (copy & paste) to see which clause is causing the exception.

Related

Converting a program from console to windows form C#

I am trying to convert a program from console to windows form but the problem is that the output is not showing on my textbox. My program is that user inputs how many number of rows.
int n = int.Parse(textbox1.Text);
int counter1 = 1,counter2 = 1,size = n + n -1;
for(int i = 0;i<size;i++){
for(int j = 0;j<size;j++){
if(i<n-1){
if(j<n-1){
if(i == j){
textBox2.Text = "{0} " + counter1;
counter1++;}
else{
textBox2.Text = " ";
} }
else{
if(i + j == size-1){
textBox2.Text = "{0} " + counter2;
counter2++;}
else{
textBox2.Text = " ";
}
} }
else if(i == n- 1 && j == n-1){
textBox2.Text = "{0} " + counter1;
counter1--;
counter2--; }
else if(i == n-1 && j != n-1){
textBox2.Text = " ";
}
else if(i > n-1){
if(j>n-1){
if(i == j){
textBox2.Text = "{0} " + counter1;
counter1--;
}
else{
textBox2.Text = " ";
} }
else
{
if(i + j == size-1){
textBox2.Text = "{0} " + counter2;
counter2--;
}
else{
textBox2.Text = " ";
}
} } }
textBox2.Text = " ";
}
The program is to display the input x number pattern. Thanks in advance.
You are resetting the text of textBox2 every time. You should use the += operator instead of =.
Side note: You should also use the special '\n' character when you need a new line.

c# how to color each lines in richtextbox

I need to color each line depends on the last char in each string form list. This is my code and it's always make the last line green. What's wrong with it?
List<string> plik = File.ReadAllLines(path).ToList();
string pom;
int size = plik.Count;
richTextBox1.Clear();
for (int i = 0; i < size; i++)
{
richTextBox1.Text += "[" + i.ToString() + "]" + " " + plik[i] + Environment.NewLine;
pom =plik[i];
richTextBox1.Select(richTextBox1.GetFirstCharIndexFromLine(i), richTextBox1.Lines[i].Length);
// richTextBox1.Select(0, pom.Length);
if (pom.Substring(pom.Length - 1) == "n")
{
richTextBox1.SelectionBackColor = pom.Substring(pom.Length - 1) == "n" ? Color.Red :Color.Red;
}
if(pom.Substring(pom.Length - 1) != "n")
{
richTextBox1.SelectionBackColor = pom.Substring(pom.Length - 1) != "n"?Color.Green:Color.Green;
}
}
just replace
richTextBox1.Text += "[" + i.ToString() + "]" + " " + plik[i] + Environment.NewLine;
by
richTextBox1.AppendText("[" + i.ToString() + "]" + " " + plik[i] + Environment.NewLine);
Append the text instead of modifying it in whole. Using += will replace the entire string and hence you'll lose the set color each time. Use AppendText instead.
Also you can remove the unnecessary ifs in your code. This should work:
for (int i = 0; i < size; i++)
{
richTextBox1.AppendText("[" + i.ToString() + "]" + " " + plik[i] + Environment.NewLine);
richTextBox1.Select(richTextBox1.GetFirstCharIndexFromLine(i), richTextBox1.Lines[i].Length);
richTextBox1.SelectionBackColor = plik[i][plik[i].Length - 1] == 'n' ? Color.Red : Color.Green;
}

Check next loop iteration data unless at end of loop c#

I'm making a program which is creating an ASCII image. Based on the asterix input it produces different things. To start I'm making a basic outline however I have an issue where I cannot add something when checking last for loop iteration.
Method code:
private List<string> DrawOutline(List<string> inputLines)
{
List<string> output = new List<string>();
int door = r.Next(0, inputLines.Last().Length);
for (int li = 0; li < inputLines.Count; li++)
{
char[] curLine = inputLines[li].ToCharArray();
string outputLine1 = string.Empty;
string outputLine2 = string.Empty;
for (int i = 0; i < curLine.Length -1; i++)
{
Console.WriteLine(curLine[i]);
if (curLine[i] == '*')
{
outputLine1 += "+---";
outputLine2 += "| ";
}
else
{
outputLine1 += " ";
outputLine2 += " ";
}
if(li < curLine.Length - 1)
{
if (curLine[i] == '*' && curLine[i + 1] != '*')
{
outputLine1 += "+";
outputLine2 += "|";
}
}
}
output.Add(outputLine1);
output.Add(outputLine2);
}
return output;
}
When I run this, it works fine however will not add '+' and '|' to the last line of outputLines. This is because the line :
if(li < curLine.Length -1)
However without the -1 it will throw an exception because I am using [i+1] to decide something. Is there a way to check only if it won't throw an exception?
you can check if the end of the array has been reached by using the OR ( || ) statement. If the first statement of the OR statement returns true, the second is not checked. This is called short-circuiting. No error should be thrown in this case.
private List<string> DrawOutline(List<string> inputLines)
{
List<string> output = new List<string>();
int door = r.Next(0, inputLines.Last().Length);
for (int li = 0; li < inputLines.Count; li++)
{
char[] curLine = inputLines[li].ToCharArray();
string outputLine1 = string.Empty;
string outputLine2 = string.Empty;
for (int i = 0; i < curLine.Length -1; i++)
{
Console.WriteLine(curLine[i]);
if (curLine[i] == '*')
{
outputLine1 += "+---";
outputLine2 += "| ";
}
else
{
outputLine1 += " ";
outputLine2 += " ";
}
if (curLine[i] == '*' && (curLine.Length == i+1 || curLine[i + 1] != '*'))
{
outputLine1 += "+";
outputLine2 += "|";
}
}
output.Add(outputLine1);
output.Add(outputLine2);
}
return output;
}
Change if (li < curLine.Length - 1) to if (i < curLine.Length - 1)

Text file is always blank

I have made this timer class and when its end timer function is called it is supposed to write a text file however it only seems to create a blank file every time. any ideas why? i have checked and the date modified is always the time i last ran the function.
public class Timer100NanoSeconds
{
long startTick;
List<Tuple<string, long>> stepTicks;
readonly string functionName;
int timesRan;
public Timer100NanoSeconds(string name)
{
functionName = name;
StartNew();
}
public void StartNew()
{
timesRan = 0;
startTick = DateTime.Now.Ticks;
stepTicks = new List<Tuple<string, long>>();
}
public void AddStep(string temp)
{
stepTicks.Add(new Tuple<string, long>(temp, DateTime.Now.Ticks));
}
public void counterForTimesRan(int ran)
{
timesRan = ran;
}
public void EndTimer()
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(functionName + ".txt"))
{
file.WriteLine("Ran " + timesRan + " Times");
for (int i = 0; i < stepTicks.Count; i++)
{
if (i == 0)
{
if (stepTicks[i].Item2 - startTick != 0)
{
file.WriteLine(("" + (stepTicks[i].Item2 - startTick)).PadLeft(15, ' ') + " , " + stepTicks[i].Item1.Trim());
}
}
else
{
if (stepTicks[i].Item2 - stepTicks[i - 1].Item2 != 0)
{
file.WriteLine(("" + (stepTicks[i].Item2 - stepTicks[i - 1].Item2)).PadLeft(15, ' ') + " , " + stepTicks[i].Item1.Trim());
}
}
}
}
}
public void EndTimer(bool showZero)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(functionName + ".txt"))
{
for (int i = 0; i < stepTicks.Count; i++)
{
if (showZero)
{
if (i == 0)
{
file.WriteLine(("" + (stepTicks[i].Item2 - startTick)).PadLeft(15, ' ') + " , " + stepTicks[i].Item1.Trim());
}
else
{
file.WriteLine(("" + (stepTicks[i].Item2 - stepTicks[i - 1].Item2)).PadLeft(15, ' ') + " , " + stepTicks[i].Item1.Trim());
}
}
else
{
if (i == 0)
{
if (stepTicks[i].Item2 - startTick != 0)
{
file.WriteLine(("" + (stepTicks[i].Item2 - startTick)).PadLeft(15, ' ') + " , " + stepTicks[i].Item1.Trim());
}
}
else
{
if (stepTicks[i].Item2 - stepTicks[i - 1].Item2 != 0)
{
file.WriteLine(("" + (stepTicks[i].Item2 - stepTicks[i - 1].Item2)).PadLeft(15, ' ') + " , " + stepTicks[i].Item1.Trim());
}
}
}
}
}
}
}

Convert rule condition to rule list

I have a string which are combination of rules which I have to extract into array. AND condition are seperated by commas while OR move to next array index below are some condtion I am trying
(1 AND 2) AND (3 AND 4) => ["1,2,3,4"]
1 OR 2 => ["1","2"]
(1 OR (2 AND 3)) AND 4 => ["1,4","2,3,4"]
(1 OR 2) OR (3 OR 4) => ["1","2","3","4"]
I have tried the below approach is there a better approach than this.
static void Main(string[] args)
{
string input = "4 AND (1 OR (2 AND 3))";
List<string> output = new List<string>();
string inputTmp = input.Replace("(", "")
.Replace(")", "")
.Replace(" AND ", ",");
if (inputTmp.Contains("OR"))
{
List<string> orOutput = new List<string>();
List<List<string>> cmbOutput = new List<List<string>>();
char splitChar = ' ';
if (input.Contains(")) AND ((")) { inputTmp = input.Replace(")) AND ((", "&"); splitChar = '&'; }
else { if (input.Contains(")) AND ")) { inputTmp = input.Replace(")) AND ", "&"); splitChar = '&'; } }
if (input.Contains(")) OR ((")) { inputTmp = input.Replace(")) OR ((", "|"); splitChar = '|'; }
else { if (input.Contains(")) OR ")) { inputTmp = input.Replace(")) OR ", "|"); splitChar = '|'; } }
if (splitChar != ' ')
{
foreach (var item in inputTmp.Split(splitChar))
{
orOutput.Add(item.Replace("(", "").Replace(")", "").Replace(" AND ", ","));
}
}
else
{
orOutput.Add(input.Replace("(", "").Replace(")", "").Replace(" AND ", ","));
}
foreach (var item in orOutput)
{
List<string> lcOutput = new List<string>();
foreach (var oritem in item.Replace(" OR ", "|").Split('|'))
{
lcOutput.Add(oritem);
}
cmbOutput.Add(lcOutput);
}
if (cmbOutput.Count > 1 && splitChar == '&')
{
for (int i = 0; i < cmbOutput[0].Count; i++)
{
for (int j = 0; j < cmbOutput[1].Count; j++)
{
output.Add(cmbOutput[0][i] + "," + cmbOutput[1][j]);
}
}
}
else
{
foreach (var item in cmbOutput)
{
foreach (var initem in item) { output.Add(initem); }
}
}
}
else
{
output.Add(inputTmp);
}
output.ForEach(o => { Console.WriteLine(o); });
Console.ReadLine();
}
I've created a method that I hope meets your needs. It parses the given expression recursively.
Source code
public static string Parse(string s)
{
return '"' + InnerParse(s).Replace(";", "\",\"") + '"';
}
private static string InnerParse(string s)
{
int pos;
while ((pos = s.IndexOf('(')) != -1)
{
int count = 1;
int nextPos = pos;
while (count != 0)
{
nextPos = s.IndexOfAny(new[] { ')', '(' }, nextPos + 1);
if (nextPos == -1 || nextPos >= s.Length)
throw new ApplicationException(); // Unpaired parentheses
count = s[nextPos] == '(' ? count + 1 : count - 1;
}
s = (pos != 0 ? s.Substring(0, pos - 1) : String.Empty)
+ InnerParse(s.Substring(pos + 1, nextPos - pos - 1)) // Recursion
+ s.Substring(nextPos + 1);
}
string[] operands = s.Split(new[] { "AND", "OR" }, StringSplitOptions.None);
if (operands.Length != 2)
throw new ApplicationException(); // Count of operands != 2
string op1 = operands[0].Trim();
string op2 = operands[1].Trim();
// If operator is OR
if (s.Contains("OR"))
return op1 + ';' + op2;
// If operator is AND
string[] op1s = op1.Split(';');
string[] op2s = op2.Split(';');
string[] ret = new string[op1s.Length * op2s.Length];
int i = 0;
foreach (string s1 in op1s)
foreach (string s2 in op2s)
ret[i++] = s1 + ',' + s2;
return String.Join(";", ret);
}
Usage example
Console.WriteLine(Parse("(1 OR (2 AND 3)) AND 4"));
Restrictions
Two operators are recognized: AND, OR.
Operators are case-sensitive.
Operators have exactly two operands.
Operands cannot contain a double-quote " or a semicolon ;.

Categories

Resources