So basically I have a button that takes the strings delimited by line breaks in one text box that then formats them a particular way and puts them in a different text box. Everything looks fine when I run the code, however, when I copy and paste the text from the second textbox to a different place, it adds a line break after everything that I took from the original box.
private void ToTableButton_Click(object sender, EventArgs e)
{
StringBuilder tableText = new StringBuilder();
string[] lines = BasicTextBox.Text.Split('\n');
TableTextBox.Clear();
try
{
for (int i = 0; i < columnsUpDown.Value; i++)
{
if (i == columnsUpDown.Value - 1)
{
tableText.Append(lines[i]);
}
else
{
tableText.Append(lines[i] + " | ");
}
}
tableText.Append(Environment.NewLine);
for (int i = 0; i < columnsUpDown.Value; i++)
{
if (i == columnsUpDown.Value - 1)
{
tableText.Append("--");
}
else
{
tableText.Append("--|");
}
}
int currentPos = Convert.ToInt32(columnsUpDown.Value);
while (currentPos <= lines.Length)
{
tableText.Append(Environment.NewLine);
for (int i = 0; i < columnsUpDown.Value; i++)
{
if (i == columnsUpDown.Value - 1)
{
tableText.Append(lines[currentPos]);
}
else
{
tableText.Append(lines[currentPos] + " | ");
}
currentPos++;
}
}
}
catch
{
}
TableTextBox.Text = tableText.ToString();
}
I thought maybe this be because the split doesn't remove the \n but I wasn't sure how to remove it afterwards. Any advice would be greatly appreciated.
I would think that trimming the lines[currentPos] would be the correct way...
tableText.Append(lines[currentPos].ToString().Trim());
Related
So I did this hangman game, and it works perfectly fine, the only problem is that I want to use methods to organize everything.
And yes, it is a school project. I tried my best but whenever I try to put a part of the program in a method it's as if I removed a variable and it underlines it in red.
I removed them for now so it's more clear. also, the file I used contained 19 8 letters max words, one on each line.
Can someone tell me how I can incorporate methods without ruining the whole thing? also English isn't my first language plz excuse any mistakes, the code was in french and I translated it for this question. thank you very much. I appreciate your time and effort :)
using System;
using System.IO;
namespace TP3
{
class Program
{
public const String Dico = "dico.txt";
public static void Welcome()
{
//Mot de bienvenue
Console.WriteLine("Welcome to hangman !");
}
public static void Goodbye()
{
Console.WriteLine("thx for playing, goodbye!");
}
public static void Program()
{
int SolvedWords= 0;
string WordToGuess= "";
int NumberOfLetters ;
int x = 0;
int WordTried = 0;
Console.WriteLine("");
Console.WriteLine("Do you wanna guess a word ? oui or non.");
Console.WriteLine("you have 8 chances per word.");
string Answer= Console.ReadLine();
Answer= Answer.ToLower();
while (Answer== "oui" && WordTried <19)
{
const int Lives= 8;
int LostLives= 0;
int LivesLeft= 8;
int LettersGuesed= 0;
x += 1;
WordTried += 1;
if (WordTried <= 20 && WordTried >1)
{
Console.WriteLine("Do you wanna guess a word ? oui or non.");
Answer= Console.ReadLine();
Answer= Answer.ToLower();
}
//Read a word in the file
int compteur = 0;
string ligne;
// Read file and show on the line
System.IO.StreamReader file = new System.IO.StreamReader(#"dico.txt");
while ((line = file.ReadLine()) != null)
{
compteur++;
if (compteur == x)
{
WordToGuess= line;
}
}
file.Close();
char[] table;
table = new char[WordToGuess.Length];
for (int i = 0; i < table.Length; i++)
{
table[i] = WordToGuess [i];
}
//change each letter into a *
Console.WriteLine("here’s the word to guess : ");
string HiddenWord = "********";
char[] table2;
table2 = new char[WordToGuess.Length];
for (int i = 0; i < table2.Length; i++)
{
table2[i] = HiddenWord[i];
}
for (int i = 0; i < table2.Length; i++)
{
Console.Write(table2[i]);
}
Console.WriteLine("");
//guess the word
while (LettersGuesed< WordToGuess.Length && LivesLeft> 0)
{
Console.WriteLine("");
/* Console.WriteLine("Devinez une seule Letterdu mot. Ne pas écrire une Letter plus d'une fois de suite. Si c'est le cas, recommencez le jeu.");*/
string Letter= Console.ReadLine();
Letter= Letter.ToLower();
NumberOfLetters = Letter.Length;
char[] table3;
table3= new char[NumberOfLetters ];
for (int i = 0; i < table2.Length; i++)
{
if (table[i].Equals(Letter[0]))
{
Table2[i] = Letter[0];
LettersGuesed+= 1;
}
}
for (int i = 0; i < table2.Length; i++)
{
Console.Write(table2[i]);
}
if (WordToGuess.IndexOf(Lettre) < 0)
{
Console.WriteLine("");
Console.WriteLine("wrong letter.");
LostLives+= 1;
LivesLeft= Lives- LostLives;
Console.WriteLine("you have " + LivesLeft+ " lives left.");
}
if (WordToGuess.IndexOf(Lettre) >= 0)
{
Console.WriteLine(" ");
Console.WriteLine("right !");
Console.WriteLine("you have " + LivesLeft+ " lives left.");
}
if (LettersGuesed== WordToGuess.Length && LivesLeft> 0)
{
SolvedWords+= 1;
Console.WriteLine(" ");
Console.WriteLine("you found the word !");
Console.WriteLine("you found " + SolvedWords+ " on" + WordTried + " words so far.");
}
if (LivesLeft== 0)
{
Console.WriteLine("you couldnt guess the word.");
Console.WriteLine("the word was :");
for (int i = 0; i < table.Length; i++)
{
Console.Write(table[i]);
}
Console.WriteLine(" ");
Console.WriteLine("you found " + SolvedWords+ " on" + WordTried + " words so far.");
}
if (WordTried == 19)
{
Console.WriteLine("no more words to guess.");
}
}
}
}
static void Main(string[] args)
{
Welcome();
Programme();
Goodbye();
}
}
}
Im not going to make every method for your project, I'll help kickstart on how to think about it. Look at your current code for reading the file of words. You can move that into a method -
public string[] ReadWordsFromFile()
{
string file = "path to your file here";
return File.ReadAllLines(file);
}
Or pass the file path as parameter -
public string[] ReadWordsFromFile(string filePath)
{
return File.ReadAllLines(filePath);
}
Next you can have a method to get random words -
public string GetRandomWord(string[] wordsArray)
{
Random random = new Random();
int randomIndex = random.Next(0, wordsArray.Length);
return wordsArray[randomIndex];
}
Note - words can be repeated if you do it this way, if you don't want that - then add logic to remove that item from the list once its used in the game. If you remove it within this method, its not actually going to remove it from the game, as you'll still be passing the entire array when getting a new word. Ill leave the implementation of that logic to you, if you want it.
In the "game controller" code -
you can use the above methods like this -
string file = "your path to txt file";
string[] allWords = ReadWordsFromFile(file);
string WordToGuess = GetRandomWord(allWords);
May be your next goal should be something like this -
public void GameControler()
{
// get all words here and other logic before game starts
while (Attempts > 0)
{
string WordToGuess = GetRandomWord(wordsArray);
// get letterGuessed from user
bool letterExists = CheckIfLetterExists(WordToGuess, letterGuessed);
if (!letterExists)
{
Attempts--;
ExecuteWrongGuessMethod(x, y);
}
else
{
ExecuteRightGuessMethod(w);
}
}
}
public bool CheckIfLetterExists(string word, string letter)
{
if (word.Contains(letter)) return true;
else return false;
}
public void ExecuteWrongGuessMethod(string passWhatYouNeedTo, int somethingElse)
{
// what to do when the guess is wrong e.g. Console.Writeline("wrong guess");
}
public void ExecuteRightGuessMethod(string word)
{
// logic when guess is right. e.g. Show the letter guessed within the word on the console etc.
}
All of this isn't the best way to do it. BUT I personally feel this is logically next step a beginner takes after what you've implemented. Seeing a fully well-developed program might be too much without understanding atleast some basic concepts of OOP.
After learning how to create Methods and use them, then comes classes and objects. Which should be implemented in this game, but this is all for now. I recommend you do a short C# course on coursera etc or even youtube. And slowly move towards a better understanding of SOLID principles. And by SOLID I mean an acronym for the 5 principles and not the actual word. All the best.
im working in a project where it has to import excel file and show its details in 3 different data grid .i have a button with codes here.
private void btn1_Click(object sender, EventArgs e)
{
try
{
if (Convert.ToInt32(txtreg.Text) > 0)
{
for (int i = 0; i < dgResult1.Columns.Count; i++)
{
if (dgResult1.Columns[i].HeaderText == "REGHRS")
{
for (int j = 0; j < dgResult1.Rows.Count; j++)
{
if (Convert.ToInt32(dgResult1.Rows[j].Cells["REGHRS"].Value.ToString()) >= 12)
{
dgResult1.Rows[j].Cells["REGHRS"].Value = txtreg.Text;
dgResult2.Rows[j].Cells["REGHRS"].Value = Convert.ToInt32(dgResult2.Rows[j].Cells["REGHRS"].Value.ToString().Trim()) - Convert.ToInt32(txtreg.Text);
dgResult3.Rows[j].Cells["REGHRS"].Value = 0;
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
and it throws an error with input string was not in a correct format .can somebody help me .thanks
This is classic Debugging 101, and it's a good idea to learn it early in your career unless you're the coding Kwisatz Haderach, who can write bug-free code first time, every time :-)
Every time before you attempt a conversion with something like:
Convert.ToInt32(blah)
(I see four of those in your code, two on a single line), you should put in some temporary debug code (message box, or console writeline, or something) to find out what blah is actually set to. This should include the actual string, surrounded by [] characters, and the length of the string.
This will let you identify which string is failing the integer conversion. Once you've established that, the next step will be to work out why.
Handling Convert.ToInt32
your exception occurs by Convert.ToInt32(...) - you use it several times.. that means that in some point a string without a number passed to this function
my guess is that some field from the database contains null and represented by an empty string
althougth Convert.ToInt32 can deal with null values it fails on empty string values
a potential solution - use your own method:
int ConvertInt(string val)
{
return (val.IsNullOrEmpty(val)) ? 0 : int.Parse(val); // Parse aimed to deal with strings only while Convert deals withe several types
}
private void btn1_Click(object sender, EventArgs e)
{
int regNumber = 0;
bool regFlag = int.TryParse(txtreg.Text, regNumber)
if(!regFlag)
{
MessageBox.Show("Reg textbox doesn't have integer value");
return;
}
if(regNumber <= 0)
{
MessageBox.Show("Reg textbox has negative or 0 value");
return;
}
for (int i = 0; i < dgResult1.Columns.Count; i++)
{
if (dgResult1.Columns[i].HeaderText != "REGHRS")
continue;
for (int j = 0; j < dgResult1.Rows.Count; j++)
{
string regHrs = dgResult1.Rows[j].Cells["REGHRS"].Value.ToString();
int regValue = 0;
bool regCheck = int.TryParse(regHrs, out regValue)
if(!regCheck || reg < 12)
continue;
dgResult1.Rows[j].Cells["REGHRS"].Value = txtreg.Text;
//till now both converts should be okay.
dgResult2.Rows[j].Cells["REGHRS"].Value = Convert.ToInt32(dgResult2.Rows[j].Cells["REGHRS"].Value.ToString()) - Convert.ToInt32(txtreg.Text);
dgResult3.Rows[j].Cells["REGHRS"].Value = 0;
}
}
}
The error is that you are converting somewhere wrong integer values. Also you have really bad structure of the code. You should avoid nested if. I wrote how the code should probably look like. Also why catch system exceptions, no user cares about them. You should show relevant text.
Below is my opinion
private void btn1_Click(object sender, EventArgs e)
{
try
{
if (Convert.ToInt32(txtreg.Text) > 0)
{
for (int i = 0; i < dgResult1.Columns.Count; i++)
{
if (dgResult1.Columns[i].HeaderText == "REGHRS")
{
for (int j = 0; j < dgResult1.Rows.Count; j++)
{
if (Convert.ToInt32(dgResult1.Rows[j].Cells["REGHRS"].Value.ToString()) >= 12)
{
dgResult1.Rows[j].Cells["REGHRS"].Value = txtreg.Text;
dgResult2.Rows[j].Cells["REGHRS"].Value = Convert.ToInt32(dgResult2.Rows[j].Cells["REGHRS"].Value.ToString().Trim()) - Convert.ToInt32(txtreg.Text);
dgResult3.Rows[j].Cells["REGHRS"].Value = "0";//UpDate this
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
I got a code for line numbering, it works perfectly fine for numbering lines the regular way but I'm looking for something a little bit different. I want my code to only count line breaks when i press enter(the program receives an return keycode) and not then the textbox automatically cut the lines with word wrapping. This is the code i'm using right now:
//Instructions
int maxLC = 1; //maxLineCount - should be public
private void InstructionsSyncTextBox_KeyUp(object sender, KeyEventArgs e)
{
int linecount = InstructionsSyncTextBox.GetLineFromCharIndex(InstructionsSyncTextBox.TextLength) + 1;
if (linecount != maxLC)
{
InstructionsLineNumberSyncTextBox.Clear();
for (int i = 1; i < linecount + 1; i++)
{
InstructionsLineNumberSyncTextBox.AppendText(Convert.ToString(i) + "\n");
}
maxLC = linecount;
}
}
How i think i would be done easiest is by saving the line count every time someone presses enter to a list and also everytime someone presses enter it updates the line number texbox with every line number at positions said in list. But i have no idea how to detect when an return is removed. Anybody knows how to solve this?
Extremely basic example that counts the lines in your code you posted:
class Program
{
static void Main(string[] args)
{
string stringFromTextBox =
#" int maxLC = 1; //maxLineCount - should be public
private void InstructionsSyncTextBox_KeyUp(object sender, KeyEventArgs e)
{
int linecount = InstructionsSyncTextBox.GetLineFromCharIndex(InstructionsSyncTextBox.TextLength) + 1;
if (linecount != maxLC)
{
InstructionsLineNumberSyncTextBox.Clear();
for (int i = 1; i < linecount + 1; i++)
{
InstructionsLineNumberSyncTextBox.AppendText(Convert.ToString(i) + ""\n"");
}
maxLC = linecount;
}
}";
Regex r = new Regex("\r", RegexOptions.Multiline);
int lines = r.Matches(stringFromTextBox).Count;
//You'll need to run this line every time the user presses a key
}
}
So, I have a listbox with x number of items. On top of the listbox I have a TextBox (this is the search field). I try do develop an algorithm that removes items from the listbox, if it doesn't contain the searchword (variable keyword in the code). This is supposed to happen for each key the user types (on-the-fly). So, the code:
private void _keywordTextBox_TextChanged(object sender, EventArgs e)
{
string keyword = _keywordTextBox.Text;
if (keyword == searchtext || isSpace) // do nothing if space is typed - searchtext is a templatetext in the textbox ("type here to search...")
return; // ignore
else if (keyword == "")
{
listBox.Items.Clear();
foreach (string s in originalList)
listBox.Items.Add(s);
}
else
{
List<string> selection = new List<string>();
foreach (string s in originalList) // originalList is the listbox at startup
selection.Add(s);
listBox.BeginUpdate();
string[] keywordSplit = keyword.Split(' ');
try
{
for (int i = originalList.Count - 1; i >= 0; i--)
{
string[] selectionSplit = selection[i].Split(' ');
int l = 0; // number of hits
for (int j = 0; j < selectionSplit.Length; j++)
{
for (int k = 0; k < keywordSplit.Length; k++)
{
if (selectionSplit[j].ToLower().Contains(keywordSplit[k].ToLower()))
{
l++;
break;
}
}
}
if (l < keywordSplit.Length) // Not hit on all keywords
selection.RemoveAt(i);
}
}
finally
{
listBox.Items.Clear();
foreach (string s in selection) // Add selection in listbox
listBox.Items.Add(s);
if (listBox.Items.Count > 0)
listBox.SetSelected(0, true); // Select first item in listbox
listBox.EndUpdate();
}
}
}
The problem is hard to describe, other than it doesn't work as intended. The behavour is, as far as I can see, sporadic.
If I search for "ck flow", I should get a hit for stackoverflow. More importantly, it should also work if I deletes chars (delete key of backspace). Anybody?
Edit: more details:
The listbox should shrink and grow on each keystroke, based on what the user searches for. The listbox should keep every item that matches the keyword typed in by the user, and filter away that doesn't match.
Or you could try to work out a Regular Expression:
private void textBox1_TextChanged(object sender, EventArgs e)
{
string keyword = textBox1.Text;
if (string.IsNullOrEmpty(keyword.Trim()))
{
listBox1.Items.Clear();
listBox1.Items.AddRange(_originalList.ToArray());
}
else
{
Regex regex = new Regex(GetRegexPatternFromKeyword(keyword));
List<string> selection =
_originalList.Where(s => regex.IsMatch(s)).ToList();
listBox1.Items.Clear();
listBox1.Items.AddRange(selection.ToArray());
}
}
private static string GetRegexPatternFromKeyword(string keyword)
{
string[] words =
keyword.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(word => "(?=.*" + word.Replace(")", #"\)") + ")").ToArray();
return string.Join("", words);
}
disclaimer: there could be some cases where an input would 'destroy' the regex pattern
Your code increases l too often. For instance;
the text 'aaa aaa aaa' with searchword 'aaa bbb' will give an l of 3 because every time you find 'aaa' you increase l. So this will be a match even though 'bbb' is never found.
You can fix this (among others) by deleting found parts of keywordsplit and recreating keywordsplit anew before every search of a new selectionline.
l++;
break;
becomes
l++
keywordSplit.RemoveAt[k];
break;
and move
string[] keywordSplit = keyword.Split(' ');
to just before you start the k loop
Altough I feel there might be better ways to achieve what you want with a bit cleaner and faster code it should work.
I got it to work. #IvoTops helped me in the right direction. Just loop trough all the keyword first, and then the selections.
for (int j = 0; j < keywordSplit.Length; j++)
{
for (int k = 0; k < selectionSplit.Length; k++)
{
if (selectionSplit[k].ToLower().Contains(keywordSplit[j].ToLower()))
{
l++;
break;
}
}
}
Seems to work ok now.
I need to add functionality in my program so that any file imported it will find the text within the "" of the addTestingPageContentText method as seen below. The two values on each line will then be added to a datagridview which has 2 columns so first text in first column then second in the 2nd column. How would i go about Finding the "sometext" ?
addTestingPageContentText("Sometext", "Sometext");
addTestingPageContentText("Sometext2", "Sometext2");
... continues n number of times.
Neither fast nor efficient, but it's easier to understand for those new to regular expressions:
while (!endOfFile)
{
//get the next line of the file
string line = file.readLine();
EDIT: //Trim WhiteSpaces at start
line = line.Trim();
//check for your string
if (line.StartsWith("addTestingPageContentText"))
{
int start1;
int start2;
//get the first something by finding a "
for (start1 = 0; start1 < line.Length; start1++)
{
if (line.Substring(start1, 1) == '"'.ToString())
{
start1++;
break;
}
}
//get the end of the first something
for (start2 = start1; start2 < line.Length; start2++)
{
if (line.Substring(start2, 1) == '"'.ToString())
{
start2--;
break;
}
}
string sometext1 = line.Substring(start1, start2 - start1);
//get the second something by finding a "
for (start1 = start2 + 2; start1 < line.Length; start1++)
{
if (line.Substring(start1, 1) == '"'.ToString())
{
start1++;
break;
}
}
//get the end of the second something
for (start2 = start1; start2 < line.Length; start2++)
{
if (line.Substring(start2, 1) == '"'.ToString())
{
start2--;
break;
}
}
string sometext2 = line.Substring(start1, start2 - start1);
}
}
However I would seriously recommend going through some of the great tutorials out there on the internet. This is quite a good one
The expression "\"[^"]*\"" would find each...