Just a C# beginner here that just build his first application and now wants to make some changes to make it more ideal.
Today I got three textboxes where the users type in year, month and project number.
When they click GO the application opens the respective folder: L:\2019\01\20190133
I would like to make it simpler, one textbox that gets divided into three strings (year, month, PO-number).
Any ideas? Sorry for the bad format of this post, feel free to correct/shame me :)
Current code:
private void button1_Click(object sender, System.EventArgs e)
{
int tbyear;
int tbmonth;
int tbpnr;
tbyear = int.Parse(textBox1.Text);
tbmonth = int.Parse(textBox2.Text);
tbpnr = int.Parse(textBox3.Text);
string tby = textBox1.Text;
string tbm = textBox2.Text;
string tbnr = textBox3.Text;
string path = Path.Combine(tby, tbm);
string pathnr = textBox1.Text + textBox2.Text + textBox3.Text;
System.Diagnostics.Process.Start("explorer.exe", #"L:\" + path + "\\" + pathnr);
As a very simple example of text extraction, use Substring.
string textFromInputControl = "20190133";
string year = textFromInputControl.Substring(0, 4); // start at index 0, 4 chars long
string month = textFromInputControl.Substring(4, 2); // start at index 4, 2 chars long
string poNumber = textFromInputControl.Substring(6); // start at index 6, all remaining chars
Console.WriteLine(year); // "2019"
Console.WriteLine(month); // "01"
Console.WriteLine(poNumber); // "33"
There are, of course, more complex ways of doing text extraction, like Regex. Use other tools when they are more appropriate.
I think that it's fine as it is. If you have 3 differents inputs in 3 differents textboxes it's well designed.
Imagine that one day you make a change and you don't want to join these types for generate your path: year\month\projectNumber.
This would implies to change UI + Code. If you keep your input in only 1 text box, the changes only affect to code.
I'm not so sure that entering all three items into one textbox is simpler from a user's perspective, but if you want to do that here's one way:
This assumes that the entries are separated in some way (we'll go with a space character).
var parts = textbox.Text.Split(' ');
var pathToOpen = $#"L:\{parts[0]}\{parts[1]}\{parts[2]}";
The above code splits the contents of the textbox by its ' ' delimiter, then formats them into a path in the format you provided.
Edit: going by the comments, you don't want to have a delimiter. In the case that your first two parts of the path are of fixed length, you can use the Substring method to extract them:
var year = textbox.Text.Substring(0, 4);
var month = textbox.Text.Substring(4, 2);
var rest = textbox.Text.Substring(6);
Related
I have this code written in C# but looks kind of "bad" and I would like to shorten it somehow and keep it clean and simple.
All this code works pretty fine but I want to know if there's any other way I can achieve the same thing.
EDIT: I forgot to mention that the firstLine has a bad date format attached with it, so it is like this: "This_is_my_first_line_20220126". So I split the string and then only join it with the corrected date. The problem is that I can never know how long the new string would be and I don't want to handle the code like this and go up to 100 parts.
Here's my code:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
string firstLine = lines.FirstOrDefault();
//note: firstLine looks like this: This_is_my_first_line_20220126
string[] sub = firstLine.Split('_');
string name="";
if(sub.Length==2)
name = sub[0]+"_"+sub[1]+"_"+correctDate;
else if(sub.Length==3)
name = sub[0]+"_"+sub[1]+"_"+sub[2]+"_"correctDate;
...
else if(sub.Length==20)
name = sub[0]+"_"+ ... "_" + sub[19];
Now, my final name value should be "This_is_my_line_26012022" but I want it to depend on the length of the given string. So far I know that the maximum length would go up to 20 but I don't want my code to look like this. Can I shorten it somehow?
you can find the LastIndexOf the underscore and drop the date by using Substring:
string firstLine = "This_is_my_first_line_20220126";
string correctDate = "26012022";
string correctString = firstLine.Substring(0, firstLine.LastIndexOf("_") + 1) + correctDate;
Still a little perplexed with the split aproach, but this a way to join back all elements
string name = string.Join("_", sub.Take(sub.Length - 1).Append(correctDate));
Or use the substring method (and no need of all that split & join)
name = firstLine.Substring(0, firstLine.LastIndexOf("_") +1) + correctDate;
I forgot to mention that firstLine has a bad date format like "This_is_my_Line_20220125"
If you want to correct just the first line:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
lines[0] = lines[0][..^8] + correctDate;
[..^8] uses C# 9's "indices and ranges" feature, that allows for a more compact way of taking a substring. It means "from the start of the string, up to the index 8 back from the end of the string".
If you get a wiggly line and possibly a messages like "... is not available in C# version X" you can use the older syntax, which would be more like lines[0] = lines[0].Remove(lines[0].Length - 8) + correctDate;
If you want to correct all lines:
string correctDate = "26012022";
string[] lines = File.ReadAllLines("text.txt");
for(int x = 0; x < lines.Length; x++)
lines[x] = lines[x][..^8] + correctDate;
If the incorrect date isn't always 8 characters long, you can use LastIndexOf('_') to locate the last _, and snip it to that point
I am currently making myself a little tool.
Essentially I have this list which goes like this:
NPWR00160_00 LittleBigPlanet
NPWR00163_00 Warhawk
NPWR00179_00 Pure
NPWR00180_00 Midnight Club: Los Angeles
NPWR00181_00 echochromeâ„¢
NPWR00187_00 WipEout® HD
This is currently typed into a richTextBox.
I am trying to do this, get the NPWRXXXXXX of the line and save it as a string, and then the Games Name and save that as another string for which I can go ahead and do what I was originially going to do with it. But for each line of the richTextBox which carries on with that formation as above.
Not too sure how to get a line from the richTextBox and save it as a string, in which I can repeat that process for every single line of the richTextBox.
For what I have tried, I gave myself an example that the string was NPWR02727_00 Skydive: Proximity Flight. What I did was this:
string game = "NPWR02727_00 Skydive: Proximity Flight";
string NPWR = game.Substring(0,13);
string gamename = game.Remove(0, 13);
richTextBox2.AppendText("NPWRID: " + NPWR + " Game: " + gamename + Environment.NewLine);
Which actually does successfully save the strings and write it in the second text box as the new form.
Only issue is I'm not sure how to convert a line from the RichTextBox and turn it into a string, and repeat the process for each line in the rich text box
EDIT
So I found out how to turn a string into a line from the richTextBox..
string line = richTextBox1.Lines[0];
So this will get the first line and save it as the string "line"
This now updates the code to
string game = richTextBox1.Lines[0];
string NPWR = game.Substring(0,13);
string gamename = game.Remove(0, 13);
richTextBox2.AppendText("NPWRID: " + NPWR + " Game: " + gamename + Environment.NewLine);
Now how do I get this code to run for every line, I understand I need something to repeat it, and something to change the 0 to count up by 1 everytime it repeats?
EDIT AGAIN
Awesome, forget the above edit, thanks a lot!
I suggest you do something similar to this:
var codes = new List<string>();
var games = new List<string>();
foreach(var s in richTextBox1.Lines)
{
string[] p = s.Split(new char[] { ' ' }, 2);
if (p.Count() == 1) { continue; }
codes.Add(p[0]);
games.Add(p[1]);
}
Basically, we are declaring two Lists of the type string, to store respectively the code and the name of the game. Then we proceed in looping through the Lines property of the RichTextBox, and for each line, we split the line by the first index(space) we find; asking for a maximum of two strings, to avoid splitting any forthcoming elements; in case the name of the game contains spaces.
For the two substrings obtained, we proceed by saving the first part into the List codes, and the second one into the List games.
For further uses(traversing codes/names) we could access the two Lists
for(int c = 0; c < codes.Count; c++)
{
MessageBox.Show(codes[c] + string.Empty + games[c]);
}
My Goal: I want to parse a file and display it in a textbox. Here's the code (thanks to Aviral Singh).
private void Form1_Load(object sender, EventArgs e)
{
var path = #"C:\Users\Smith\Desktop\Settings.txt"; //Path to settings file.
RichTextBox rtb = new RichTextBox();
System.IO.StreamReader sis = new System.IO.StreamReader(path);
rtb.Text = sis.ReadToEnd();
sis.Close();
foreach (string line in rtb.Lines)
{
if (line.Contains("Installation Technical Manual:") == true)
{
string numbers = line.Substring(line.IndexOf("Installation Technical Manual:"));
textBox1.Text = numbers;
}
}
}
Text file looks like this:
My Problem: The textbox in my program displays entire line: Installation Technical Manual: (1234567890).
I just want the number with brackets (1234567890). to be displayed in the textbox. What changes should I make to the code to remove the words and just display numbers with brackets around it? Thanks for your help. :)
numbers = "(" + new String(numbers.Where(Char.IsDigit).ToArray()) + ")";
The problem is that IndexOf() is going to give you the starting position of the string which you're asking for the index of. Which in your example is going to be 0, so a Substring call that starts at 0 is going to return you the entire string.
What you really want to do is Substring(IndexOf("Installation Technical Manual:") + "Installation Technical Manual:".Length). That will give you whatever comes after your string.
Assuming you have ':' in your line always,
if(line.Contains(":"))
{
string numbers = line.Split(':')[1];
textBox1.Text = numbers;
}
The reason your code is not working as you have used the substring method as with one parameter, so it is used as :
public string Substring(
int startIndex
)
See: http://msdn.microsoft.com/en-us/library/hxthx5h6.aspx
And you are passing in, line.IndexOf("Installation Technical Manual:")
which will return ).
See here: http://msdn.microsoft.com/en-us/library/k8b1470s.aspx
So you are essentially saying return Substring of string Installation Technical Manual:(number) starting at 0 which basically returns the whole line.
I need to locate a specific part of a string value like the one below, I need to alter the "Meeting ID" to a specific number.
This number comes from a dropdownlist of multiple numbers, so I cant simply use find & replace. As the text could change to one of multiple numbers before the user is happy.
The "0783," part of the string never changes, and "Meeting ID" is always followed by a ",".
So i need to get to "0783, INSERT TEXT ," and then insert the new number on the Index Changed event.
Here is an example :-
Business Invitation, start time, M Problem, 518-06-xxx, 9999 999
0783, Meeting ID, xxx ??
What is the best way of locating this string and replacing the test each time?
I hope this makes sense guys?
Okay, so there are several ways of doing this, however this seems to be a string you have control over so I'm going to say here's what you want to do.
var myString = string.Format("Business Invitation, start time, M Problem, 518-06-xxx, 9999 999 0783, {0}, xxx ??", yourMeetingId);
If you don't have control over it then you're going to have to be a bit more clever:
var startingIndex = myString.IndexOf("0783, ");
var endingIndex = myString.IndexOf(",", startingIndex + 6);
var pattern = myString.Substring(startingIndex + 6, endingIndex - (startingIndex + 6));
myString = myString.Replace(pattern, yourMeetingId);
You should store your "current" Meeting ID in a variable, changing it along with your user's actions, and then use that same global variable whenever you need the string.
This way, you don't have to worry about what's inside the string and don't need to mess with array indexes. You will also be safe from magic numbers / strings, which are bound to blow up in your face at some point in the future.
You can try with Regex.Replace method
string pattern = #"\d{3},";
Regex regex = new Regex(pattern);
var inputStr = "518-06-xxx, 9999 999 0783";
var replace = "..."
var outputStr = regex.Replace(inputStr, replace);
use Regex.Split by token "0783," then in the second string in the array return split by token "," the first element in the string array would be where you would insert new text. Then use string.Join to join the first split with "0783," and the join the second with ",".
string temp = "Business Invitation, start time, M Problem, 518-06-xxx, 9999 999 0783, Meeting ID, xxx ??";
string newID = "1234";
string[] firstSplits = Regex.Split(temp, "0783,");
string[] secondSplits = Regex.Split(firstSplits[1], ",");
secondSplits[0] = newID;
string #join = string.Join(",", secondSplits);
firstSplits[1] = #join;
string newString = string.Join("0783,", firstSplits);
I am generating 35 strings which have the names ar15220110910, khwm20110910 and so on.
The string contains the name of the Id (ar152,KHWM), and the date (20110910). I want to extract the Id, date from the string and store it in a textfile called StatSummary.
My code statement is something like this
for( int 1= 0;i< filestoextract.count;1++)
{
// The filestoextract contains 35 strings
string extractname = filestoextract(i).ToString();
statSummary.writeline( extractname.substring(0,5) + "" +
extractname.substring(5,4) + "" + extractname.substring(9,2) + "" +
extractname.substring(11,2));
}
When the station has Id containing 5 letters, then this code executes correctly but when the station Id is KHWM or any other 4 letter name then the insertion is all messed up. I am running this inside a loop. So I have tried keeping the code as dynamic as possible. Could anyone help me to find a way without hardcoding it. For instance accessing the last 8 elements to get the date??? I have searched but am not able to find a way to do that.
For the last 8 digits, it's just:
extractname.Substring(extractname.Length-8)
oh, I'm sorry, and so for your code could be:
int l = extractname.Length;
statSummary.WriteLine(extractname.substring(0,l-8) + "" +
extractname.Substring(l-8,4) + "" + extractname.Substring(l-4,2) + "" +
extractname.Substring(l-2,2));
As your ID length isn't consistent, it would probably be a better option to extract the date (which is always going to be 8 chars) and then treat the remainder as your ID e.g.
UPDATED - more robust by actually calculating the length of the date based on the format. Also validates against the format to make sure you have parsed the data correctly.
var dateFormat = "yyyyMMdd"; // this could be pulled from app.config or some other config source
foreach (var file in filestoextract)
{
var dateStr = file.Substring(file.Length-dateFormat.Length);
if (ValidateDate(dateStr, dateFormat))
{
var id = file.Substring(0, file.Length - (dateFormat.Length+1));
// do something with data
}
else
{
// handle invalid filename
}
}
public bool ValidateDate(stirng date, string date_format)
{
try
{
DateTime.ParseExact(date, date_format, DateTimeFormatInfo.InvariantInfo);
}
catch
{
return false;
}
return true;
}
You could use a Regex :
match = Regex.Match ("khwm20110910","(?<code>.*)(?<date>.{6})" );
Console.WriteLine (match.Groups["code"] );
Console.WriteLine (match.Groups["date"] );
To explain the regex pattern (?<code>.*)(?<date>.{6}) the brackets groups creates a group for each pattern. ?<code> names the group so you can reference it easily.
The date group takes the last six characters of the string. . says take any character and {6} says do that six times.
The code group takes all the remaining characters. * says take as many characters as possible.
for each(string part in stringList)
{
int length = part.Length;
int start = length - 8;
string dateString = part.Substring(start, 8);
}
That should solve the variable length to get the date. The rest of the pull is most likely dependent on a pattern (suggested) or the length of string (when x then the call is 4 in length, etc)
If you ID isn't always the same amount of letters you should seperate the ID and the Date using ',' or somthing then you use this:
for( int 1= 0;i< filestoextract.count;1++)
{
string extractname = filestoextract[i].ToString();
string ID = extractname.substring(0, extractname.IndexOf(','));
string Date = extractname.substring(extractname.IndexOf(','));
Console.WriteLine(ID + Date);
}