Adding values to a string array in C# - c#

I am building a calendar. Here I want to add members to my meeting. After every name I want to press enter to add it. When I press, for example X I want to leave the "add member" process and go to next step, for example, "adding a meeting title".
How can I add members to my array? How can I go to the next step when I'm done entering names? This code doesn't work:
Console.Write("Enter members here: ");
memberList = Console.ReadLine();
string[] memberList;

You'll need to use a conditional loop to accomplish this, a while loop would work pretty good.
Also, using a List<string> would be better in this scenario since you (i) need to add things to it, and (ii) you don't know how big to make the array when you first declare it since you don't know how many names the user will enter.
Something like:
var names = new List<string>();
var input = Console.ReadLine();
while (input.ToUpper() != "X")
{
names.Add(input);
input = Console.ReadLine();
}
foreach (var name in names)
{
Console.WriteLine(name);
}
If you're wanting to move to the next step immediately after an user presses X (without them having to press Enter), you can look into using Console.ReadKey but it'd be more complicated since you'd have to collect one character at a time to get the name and check if they key pressed is Enter, in which case you'd move on to the next name. There's also the complexity of known when a "X" is just part of someone's name, e.g. Xavier, or whether meant to move on to the next step.

Assuming the user types in the following: "Jake, Julia, Craig"
string[] memberlist = Console.ReadLine().Split(',');
Eventually you need to .Trim() on every name cause of the whitespace after the comma.
Edit: For a "multiline" solution look at #Jeff Bridgman post.

Related

C# Refine class property which is a List<string>

I have a class property:-
public List<string> szTypeOfFileList{get;set;}
As the name suggest, the property stores user selection of types of Files of interest (.txt, .doc, .rtf, .pdf, etc).
I am trying to assess whether there is way I could refine this List as it is being populated by user entries OR, if I should wait for all entries and then call a separate method to refine the property.
What I mean by this is, let's say a particular user input is ".doc/.docx". Currently, this would be stored in the List as a single string item. However I want it to be stored as two items separately. This will keep the code in one place and wont effect future modules and such.
private List<string> _szTypeOfFileList = new List<string>();
public List<string> szTypeOfFileList
{
get
{
return _szTypeOfFileList;
}
set
{
// Some kind of validation/refining method here ?? //
}
}
EDIT:-
Because my FileTypeList is coming from a checkboxList, I had to use a different methodology than the answer I accepted (which pointed me in the right direction).
foreach (object itemchecked in FileTypeList.CheckedItems)
{
string[] values = itemchecked.ToString().Split('/');
foreach(var item in values)
TransactionBO.Instance.szTypeOfFileList.Add(item);
}
This part of my code is in the UI class before it is passed on to the Business class.
If you know that it'll always be split with a "/" character, just use a split on the string. Including a simple bit of verification to prevent obvious duplicates, you might do something along the lines of:
string[] values = x.Split('/');
foreach (string val in values) {
if (!_szTypeOfFileList.Contains(val.ToLower().Trim())) {
_szTypeOfFileList.Add(val.ToLower().Trim());
}
}
You can also use an array of characters in place of the '/' to split against, if you need to consider multiple characters in that spot.
I would consider changing the List to something more generic. Do they really need a List ...or maybe a collection? array? enumerable ? (have a read through this link )
second, in your Set method, you'll want to take their input, break it up and add it. Here comes the question: is a list the best way of doing it ?
What about duplicate data ? do you just add it again? do you need to search for it in order to figure out if you're going to add it ?
Think about dictionary or hashtable, or any of type of collection that will help you out with your data . I would have a read through : this question (oh my ... wrong link ... nobody complained though ... so much for providing links ... :)
var extensions = userInput.Split('/').ToList();

C# - Passively checking for key press

I am not using windows forms so this is not a duplicate of Capture keystroke without focus in console. Please remove the duplicate label or direct me somewhere else
So have been away from C# for a long time and trying to get back into it. I am messing with a small console app that requires inputting text from the user. The whole program works fine but now I want to add a check to see if escape is ever pressed.
I originally used ReadKey, but that just checks the current key which has two problems.
1. it uses the key pressed, so strings are missing a character (the one which was checked)
2. it is only in the moment. I want it to be passively waiting until its pressed
What would be the best way to do this?
ex:
I type the string "Hello World!"
If I press the desired key(lets say escape) at any time, I want it to react. Otherwise the string should be entered like normal
edit
example of made up dictionary program (yes, I know there is already a class for this)
while (Console.ReadKey().Key != ConsoleKey.Escape)
{
string entry = Console.ReadLine();
if (!entry.Contains(","))
{
...
}
else
{
...
}
}
Thank you all very much for your time.
Not sure what you're getting at but you can use this to detect if the Escape key was pressed.
if (Console.KeyAvailable)
if (Console.ReadKey(true).Key == ConsoleKey.Escape)
{
// Do something
}
}
Or alternatively use a loop that breaks when Escape is entered:
var x = Console.ReadKey();
while (x.Key.ToString() != "Escape")
x = Console.ReadKey();

Sum up two steps into one step

In a class in a console application I wrote a method that reads many integer inputs and sums them up. The inputs calls for another method written in another class (Input.ReadIntegerConsole()) that's supposed to read the input, and then make the operations of the first class continue if the input is an integer, or otherwise to write "invalid choice", this way:
private void ReadInputAndSumNumbers()
{
Console.Write("\nNumber you choose? ");
int.TryParse(Console.ReadLine(), out numberChosen);
numberChosen = Input.ReadIntegerConsole();
sum += numberChosen;
etc. The problem is that this way, when I run the application, the console asks: Number you choose? then whatever I input, the program does nothing. At this point I will put another input and only now the ReadIntegerConsole method starts: if it is an integer the operations continue, otherwise the program displays "invalid choice". How to do it so the program does everything in one step instead of two steps, so it reads my input and immediately verifies if it is an integer or not and decides to continue or to display "invalid choice"? How to do it without having to write two inputs? I know for sure that the Input.ReadIntegerConsole code is written correctly and that's why I didn't display it here. I tried writing in many different parts of the class that numberChosen = Input.ReadIntegerConsole() but it has never worked. I tried also writing numberChosen=int.Parse(ConsoleReadLine())=Input.ReadIntegerConsole() but of course it doesn't work.
Console.Write("\nNumber you choose? ");
int.TryParse(Console.ReadLine(), out numberChosen);
numberChosen = Input.ReadIntegerConsole();
sum += numberChosen;
You didn't provide the implementation of Input.ReadIntegerConsole but its a fair guess that it also calls Console.ReadLine and parses it into an int (same as the line above it). So basically, your code is doing:
Print a message
Wait for user input, parse into an int and store in numberChosen
Call Input.ReadIntegerConsole which likely waits for user input, parses it into an int and returns it, and store it in numberChosen
Add the number to sum
So when you input the first number, it does exactly what you think, but Input.ReadIntegerConsole asks for another input and overwrites the original one (hence if you enter junk, it says "invalid value"). This second read from the console explains why the program appears to do nothing, since its waiting for more input.
Removing the manual Console.ReadLine gets rid of the redundant read/parse, which is why it fixed your code. Its not that it works without Console.ReadLine, its that the method you are using hides a call to it.
If you're asking what I think you're asking, I think you want this:
private void ReadInputAndSumNumbers()
{
Console.Write("\nNumber you choose? ");
int numberChosen;
if(int.TryParse(Console.ReadLine(), out numberChosen)) {
sum += numberChosen;
}
else {
Console.WriteLine("Invalid choice.");
}
}
int.TryParse is a method with an out parameter, which means the result of parsing will be assigned to numberChosen. It returns a bool, however: true if successful (string passed is parseable into an int), or false if unsuccessful. So what it's saying is:
If int.TryParse can create an int from the input string, the variable numberChosen has the result stored when the method finishes; add numberChosen to sum.
else, it was unsuccessful, and write "Invalid choice".
Out parameters can get a little confusing, but they're powerful. But if I did a poor job explaining, here are some links: Int32.TryParse, out (C# reference)

C#, Skipping Console.ReadLine(); Console.Read(); while in loop

If I run my code and insert correct value first time program works fine and does its job, but if I input wrong path and allow for loop to spin second time it skips path=Console.ReadLine(); but it does not skip j = (char)Console.Read(); same thing persist through out the remaining code.
do
{
Console.WriteLine("Insert path:");
path = Console.ReadLine();
temp1 = CheckPath(path); //checks if inserted value is legit
if (temp1 == false)
{
Console.WriteLine("\nDo you want to skip this step(by default directory will be set to Desktop)? Y/N ");
j = (char)Console.Read();
if (j.Equals('Y') || j.Equals('y'))
{
path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
temp1 = true;
}
}
//User inputs y/Y loop will end and exit with either path chosen by user or with desktop path
} while (!temp1);
path = Console.ReadLine(); is being skipped if user fails to insert correct path. Been looking for the solution since yesterday and I have failed to find identical problem on the web. Link to full code: Code.
The call isn't being skipped - the problem is that Console.Read() will only return after the user has hit return - although it will only consume the first character it reads. So suppose that (when prompted about skipping) the user enters:
Nfoo
and then hits return... the value of path in the next iteration will be foo.
The simplest fix is probably to convert your Console.Read() call into Console.ReadLine() and just handle the situation where the user types more than one character.
It's much more useful to use Console.ReadKey for that - it will read exactly one key, and will not require you to press enter.

C# Saving "X" times into one .txt file without overwriting last string

Well, now i have a new problem.
Im writing code in C#
I want to save from textBoxName into group.txt file each time i enter string into textbox and click on save button. It should save at this order (if its possible to sort it like A-Z that would be great):
1. Petar Milutinovic
2. Ljiljana Milutinovic
3. Stefan Milutinovic
4. ... etc
I cant get it to work, i tried to use tehniques from my first question, and no solution yet :(
This is easy one i guess, but im still a beginer and i need this baddly...
Try to tackle this from a top-down approach. Write out what should happen, because it's not obvious from your question.
Example:
User enters a value in a (single-line?) textbox
User clicks Save
One new line is appended to the end of a file, with the contents of the textbox in step 1
Note: each line is prefixed with a line number, in the form "X. Sample" where X is the line number and Sample is the text from the textbox.
Is the above accurate?
(If you just want to add a line to a text file, see http://msdn.microsoft.com/en-us/library/ms143356.aspx - File.AppendAllText(filename, myTextBox.Text + Environment.NewLine); may be what you want)
Here's a simple little routine you can use to read, sort, and write the file. There are loads of ways this can be done, mine probably isn't even the best. Even now I'm thinking "I could have written that using a FileStream and done the iteration for counting then", but they're micro-optimizations that can be done later if you have performance issues with multi-megabyte files.
public static void AddUserToGroup(string userName)
{
// Read the users from the file
List<string> users = File.ReadAllLines("group.txt").ToList();
// Strip out the index number
users = users.Select(u => u.Substring(u.IndexOf(". ") + 2)).ToList();
users.Add(userName); // Add the new user
users.Sort((x,y) => x.CompareTo(y)); // Sort
// Reallocate the number
for (int i = 0; i < users.Count; i++)
{
users[i] = (i + 1).ToString() + ". " + users[i];
}
// Write to the file again
File.WriteAllLines("group.txt", users);
}
If you need the file to be sorted every time a new line is added, you'll either have to load the file into a list, add the line, and sort it, or use some sort of search (I'd recommend a binary search) to determine where the new line belongs and insert it accordingly. The second approach doesn't have many advantages, though, as you basically have to rewrite the entire file in order to insert a line - it only saves you time in the best case scenario, which occurs when the line to be inserted falls at the end of the file. Additionally, the second method is a bit lighter on the processor, as you aren't attempting to sort every line - for small files however, the difference will be unnoticeable.

Categories

Resources