I want to keep reading lines of the user, but when this user presses on escape I want it to stop. But how can I keep reading single keys (for the escape), while meanwhile reading lines? I hope the question will be more clear after giving my code:
int number;
do
{
string a = Console.ReadLine();
try
{
Int32.TryParse(a, out number);
}
catch
{
Console.WriteLine("I only accept int");
}
finally
{
Console.Writeline(number);
}
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);
as you have written, you want to read lines until escape is pressed, but as your code says, you want to read only integers. Here's what I think is what you want,
int number = 0;
do
{
while (!Console.KeyAvailable)
{
string a = Console.ReadLine();
bool bWriteNumber = false;
try
{
number = int.Parse(a);
bWriteNumber = true;
}
catch
{
Console.WriteLine("Sorry! I only accept int");
}
finally
{
if (bWriteNumber)
Console.WriteLine(number);
}
}
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);
I am not sure to understand completely your question but you can test the code below if it matches your requirements
using System;
using System.Globalization;
namespace StackOverflow_31111668
{
class Program
{
static void Main()
{
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
var a = Console.ReadLine();
int number;
Console.WriteLine(!int.TryParse(a, out number) ? "I only accept int" : number.ToString(CultureInfo.InvariantCulture));
}
}
}
}
Related
Suppose a user is asked for the manual. Now we all know that manuals are handy and extensive, how do I collapse/clear for instance so that the user can proceed to the next activity? By pressing C after pressing M, I want the user to immediately jump to the next acitivity.
How do I remove this?
Here is the code:
static void Main(string[] args)
{
Console.WriteLine("Do you want to play the game?\nPress Y to continue\tPress M to view the rules\tEnter any key to exit. ");
string iQuestion = Console.ReadLine();
if (iQuestion.Equals("y", StringComparison.OrdinalIgnoreCase))
{
ProjectExecution();
Console.WriteLine("\nWorld you like to try again?\nPress y to play again\tEnter any key to exit. ");
string ask = Console.ReadLine();
if (ask.Equals("y", StringComparison.OrdinalIgnoreCase))
{
ProjectExecution();
}
else
{
Console.WriteLine("Thank you for playing");
}
Console.Read();
}
else if (iQuestion.Equals("m", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("Hwewewe\nPress C to continue");\\This is just an example
string mQuestion = Console.ReadLine();
if (mQuestion.Equals("c", StringComparison.OrdinalIgnoreCase))
{
Console.Clear();
ProjectExecution();
Console.Read();
}
}
else
{
Environment.Exit(10);
}
}
I am open to another solution.
I'm remaking a text-based adventure game. During the character creation, I'd like for the user, at any time, to type 'skillset' and list all the traits that a specific race has. I've tried for a couple hours and can't seem to figure it out.
This is my character creation class.
public string userCommand_SeachSkill;
SkillSet searchSkill = new SkillSet();
public void Create_Character()
{
// CHOOSE GENDER //
do
{
validate = 0;
Console.Clear();
Console.Write("Are you male or female? (f/m): ");
Sex = Console.ReadLine().ToUpper();
if (Sex == "M" || Sex == "F")
{
validate = 1;
}
else if (Sex != "M" || Sex != "F")
{
Console.WriteLine("You must enter 'm' or 'f'");
}
} while (validate == 0);
And this is my Skill Set Class. Everything in the if/else statements are methods to print the traits of a race to the console. Let me know if there is anything else I can add to better ask my question. Thank you in advance! :)
ClassAttributes classes = new ClassAttributes();
Character character = new Character();
skillset = Console.ReadLine().ToUpper();
do
{
validate = 0;
if (skillset == "HUMAN")
{
classes.SkillSetHuman();
}
else if (skillset == "ORC")
{
classes.SkillSetOrc();
}
else if (skillset == "ELF")
{
classes.SkillSetElf();
}
else if (skillset == "EXIT")
{
validate = 1;
character.Create_Character();
}
} while (validate == 0);
I think you're looking for something like an event. C# Console Applications only seem to have one kind of event, it fires when ctrl+c or ctrl+break happens. You could handle your skillset input/output logic in the function handler
You can read more here:
https://msdn.microsoft.com/library/system.console.cancelkeypress(v=vs.110).aspx
If you really need the word to be typed, you could capture everything that is typed in a special function, instead of using regular Console.ReadLine(). Something like this:
public static string CustomReadLine()
{
ConsoleKeyInfo cki;
string capturedInput = "";
while (true)
{
cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.Enter)
break;
else if (cki.Key == ConsoleKey.Spacebar)
{
capturedInput += " ";
Console.Write(" ");
}
else if (cki.Key == ConsoleKey.Backspace)
{
capturedInput = capturedInput.Remove(capturedInput.Length - 1);
Console.Clear();
Console.Write(capturedInput);
}
else
{
capturedInput += cki.KeyChar;
Console.Write(cki.KeyChar);
}
if (capturedInput.ToUpper().Contains("SKILLSET"))
{
capturedInput = "";
skillsetTyped();
return "";
}
}
return capturedInput;
}
then inside your Create_Character, do
...
do
{
Console.Write("Are you male or female? (f/m): ");
Sex = CustomReadLine();
} while (String.IsNullOrEmpty(sex));
And finally, handle the skillset logic here
protected static void skillsetTyped()
{
Console.Write("\nWrite your skillset capture/display logic here\n");
}
This is just a draft and has some minor bugs, but I believe it's close to what you really want.
I need to check a set of user Input from my console application before triggering my method and store data into my database.
The program compiles and rund without exceptions. But in case of one wrong Input it still runs through for the other three.
Although, what I really need is to make sure the 4 user's entries are correct before triggering the method and in case just one is wrong the whole program should stop and exit.
using System;
using System.Threading;
namespace BarcodeValidation
{
class Program
{
static void Main(string[] args)
{
ReadBarcode();
}
static void ReadBarcode()
{
var barcodes = GetInput();
foreach (var item in barcodes)
{
// something
CheckUserInput(item);
}
}
static string[] GetInput()
{
Console.WriteLine("Please enter 4 products ID, Barcodes, MPN or EAN code:");
string[] barcode = new string[4];
for (int i = 0; i < barcode.Length; i++)
{
barcode[i] = Console.ReadLine();
}
return barcode;
} // end of method here
static void CheckUserInput(string userInput)
{
int msec = 5000;
try
{
if (!(userInput == "F5121" || userInput == "F3111" || userInput == "F8331" || userInput == "F5321"))
{
Console.WriteLine("Enter a valid MPN codes for your products");
Thread.Sleep(msec);
Environment.Exit(0);
}
else
{
switch (userInput)
{
case "F5121":
Console.WriteLine("barcode 1 is =", userInput);
Thread.Sleep(msec);
break;
case "F3111":
Console.WriteLine("barcode 2 is =", userInput);
Thread.Sleep(msec);
break;
case "F8331":
Console.WriteLine("barcode 3 is =", userInput);
Thread.Sleep(msec);
break;
case "F5321":
Console.WriteLine("barcode 4 is =", userInput);
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Since you have a method that actually tests your user input use it's return value:
static bool CheckUserInput(string userInput) // true : valid | false : invalid
{
int msec = 5000;
try
{
if (!(userInput == "F5121" ||
userInput == "F3111" ||
userInput == "F8331" ||
userInput == "F5321"))
{
Console.WriteLine("Enter a valid MPN codes for your products");
return false;
}
else
{
switch (userInput)
{
case "F5121":
Console.WriteLine("barcode 1 is =", userInput);
Thread.Sleep(msec);
return true;
case "F3111":
Console.WriteLine("barcode 2 is =", userInput);
Thread.Sleep(msec);
return true;
case "F8331":
Console.WriteLine("barcode 3 is =", userInput);
Thread.Sleep(msec);
return true;
case "F5321":
Console.WriteLine("barcode 4 is =", userInput);
return true;
default:
return false;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
ReadBarcodes could look like this:
static void ReadBarcode()
{
var barcodes = GetInput();
bool errorOccured = false;
foreach (var item in barcodes)
{
// something
if(!CheckUserInput(item))
{
errorOccured = true; // keep track of that error
break; //Break for if 1 input is invalid
}
}
//Further execution....
if(errorOccured)
{
return; //Do not continue ...
}
//Do other things you want to do. Your input is valid at this point !
}
or shorter like Default quoted:
static void ReadBarcode()
{
if(!GetInput().All(CheckUserInput))
{
return;
}
//Your stuff goes here. Input is valid at this point
}
One option you could employ is create your own class that derives from System.Exception, and in cases where one of the inputs is found to be invalid, you could throw an instance of your exception class.
You could wrap your code in a try-catch block, and then put the remediation code within the catch block.
You need to break the checking code and the "output" code into different places. You need to check if all the values are valid values. and AFTER you have checked all the values, then do your console.writelines (Which is the part you dont want to happen). At the moment it checks one and executes the code if that one is valid, and then moves on to the next one. CheckUserInput should really ONLY check the users input, it should not do something else you want to restrict based on that methods result. You should have CheckUserInput and a ExecuteBarcodeStuff for example, and only if all CheckUserInputs return true, should you run the new (as yet unimplemented) ExecuteBarcodeStuff
Mixing this approach with other peoples answers that do Linq queries or such to ensure all the results were positive matches will get you the result you desire.
Trying to complete a stock system in a console application and thus I am stuck on this part, to make sure that a user can't have a duplicate 8 digit long ID number, my issue is as follows.
Basically I am unsure why this code will not work, I'm probably missing a very obvious piece of code here, help would be appreciated, have tried changing values around already so have more than likely overlooked a value.
static int checkIDNumber(int ID)
{
// Check the number passed in & then loop through all the lines...
// If number is taken then output error, because id exists already
// Else allow the value to be used in the stock system.
int IDNumber = ID;
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
string lineValues;
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(IDNumber.ToString()))
{
Console.WriteLine("Id number is currently already taken.");
}
else
{
return IDNumber;
}
}
}
}
I pass in my value from this line in another procedure where it is defined in the local scope.
stockID = checkIDNumber(stockID);
Here is the full code:
class Program
{
static void Main(string[] args)
{
char menuOption = '0';
while (menuOption != '3')
{
DisplayMenuOption();
menuOption = GetMenuOption();
switch (menuOption)
{
case '1':
AddStock();
break;
case '2':
CheckStock();
break;
case '3':
Console.WriteLine("Goodbye");
break;
default:
Console.WriteLine("That is not a valid option");
break;
}
}
// Keep it all happy for a screenshot ;)
Console.ReadLine();
}
static void DisplayMenuOption()
{
Console.WriteLine("Do you wish to Add Stock(1) or Check Stock(2) or Exit(3)?");
}
static void DisplayStockOption()
{
Console.WriteLine("Do you want to search by ID(1) or by Name(2), Delete current stock(3) or Exit(4)?");
}
static char GetMenuOption()
{
char userChoice = '0';
userChoice = Convert.ToChar(Console.ReadLine());
return userChoice;
}
static void CheckStock()
{
char menuOption = 'a';
while (menuOption != '4')
{
DisplayStockOption();
menuOption = GetMenuOption();
switch (menuOption)
{
case '1':
SearchID();
break;
case '2':
SearchName();
break;
case '3':
RemoveStock();
break;
case '4':
Console.WriteLine("Goodbye");
break;
default:
Console.WriteLine("That is not a valid option");
break;
}
}
}
static void RemoveStock()
{
List<string> tempList = new List<string>();
string lineValues = "";
bool found = false;
int ID = 0;
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
Console.Write("Please enter the ID number to delete: ");
ID = Convert.ToInt32(Console.ReadLine());
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(ID.ToString()) == false)
{
tempList.Add(lineValues);
}
else
{
found = true;
}
}
}
if (found == true)
{
using (StreamWriter sw = new StreamWriter("Stockfile.txt", false))
{
for (int i=0; i < tempList.Count; i++)
{
sw.Write(tempList[i]);
sw.WriteLine();
}
}
}
}
static void SearchName()
{
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
string name;
Console.Write("Please enter the name: ");
name = Console.ReadLine();
while (sr.EndOfStream == false)
{
string lineValues = sr.ReadLine();
if (lineValues.Contains(name))
{
Console.WriteLine("{0}", lineValues);
}
else
{
Console.WriteLine("{0} does not exist in this stock system!",name); // Could try to match a similar string incase of spelling errors here, although after looking at it it may be a bit far for what is being required now, but in the real world application this would be a must else people would mistype words thus not having an exact match.
}
}
}
}
static void SearchID()
{
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
int IDNumber;
string lineValues;
Console.Write("Please enter the ID number: ");
IDNumber = Convert.ToInt32(Console.ReadLine());
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(IDNumber.ToString()))
{
Console.WriteLine("{0}", lineValues);
}
else
{
Console.WriteLine("{0} does not exist in this stock system!", IDNumber); // Could try to match a similar string incase of spelling errors here, although after looking at it it may be a bit far for what is being required now, but in the real world application this would be a must else people would mistype words thus not having an exact match.
}
}
}
}
static int checkIDNumber(int ID)
{
// Check the number passed in & then loop through all the lines...
// If number is taken then output error, becuase id exists already
// Else allow the value to be used in the stock system.
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
int IDNumber;
string lineValues;
Console.Write("Please enter the ID number: ");
IDNumber = Convert.ToInt32(Console.ReadLine());
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(IDNumber.ToString()))
{
Console.WriteLine("Id number is currently already taken.");
}
else
{
ID = IDNumber;
return ID;
}
}
}
}
static void AddStock(int IDNumber)
{
using (StreamWriter sw = new StreamWriter("Stockfile.txt", true))
{
int stockID = 0;
int stockQuantity = 0;
double stockPrice = 0.00;
string stockName = "";
string s = ""; // Being Lazy here, to convert to when needed.
while (stockID.ToString().Length != 8)
{
Console.Write("Please enter the stock ID number: ");
stockID = Convert.ToInt32(Console.ReadLine());
}
s = stockID.ToString();
sw.Write(s + "\t"); // Will only accept an 8 figure digit so is safe to have a single value here.
while (stockName.Length <= 2) // No fancy brands here......
{
Console.Write("Please enter the name of the stock: ");
stockName = Console.ReadLine();
}
s = stockName;
sw.Write(s + "\t");
while (stockQuantity < 1) // Running a small shop here...
{
Console.Write("Please enter the quanity of stock: ");
stockQuantity = Convert.ToInt32(Console.ReadLine());
}
s = stockQuantity.ToString();
sw.Write(s + "\t");
while (stockPrice < 0.01) // Running a very small shop....
{
Console.Write("Please enter the price of the stock: ");
stockPrice = Convert.ToDouble(Console.ReadLine());
}
s = stockPrice.ToString();
sw.Write(s + "\t");
sw.WriteLine(); // TO create the new line.....
}
}
}
}
The problem is that you're only returning a value from inside the else block.
Your method needs to return a value regardless of which path the program takes through your code. You can fix this in any number of ways, depending on your requirements. For instance, you can have a "catch-all" return value at the bottom of the method so that if it passes through all your tests (i.e. if blocks) and reaches the bottom, as long as that's a meaningful result, it will return the catch-all value.
Alternatively, you could just make sure you put a return statement inside each of the code paths. For that, you'd need to add a return in the if portion of your if block, but you'd likely also still need a return outside of your while loop since that may never execute.
Again, it all depends on your needs.
It's at least logically possible that the file contains nothing but the ID. For example, if I enter "10" as an ID and the file is:
10
10
10
10
...
It might be the case that you know that that'll never actually happen, but the compiler can't really prove that it won't. From the compiler's "perspective," there's not really a difference between "might happen" and "can't prove that it won't happen."
Also, your logic is wrong. If you know that the user requested a duplicate ID, you don't need to check the rest of the file - you already know it's a duplicate.
Right now, if the first line of the file isn't the ID they requested, it'll allow the user to take it. For example, if the user requested "9" as an ID and the file is as follows:
3 -- It only actually checks this line
5
9 -- Obviously the ID is already taken here but it'll never check this line
2
1
See my comments below:
// I'd suggest making this "bool" - they already know what the ID number is,
// so there's no point in returning it back to them
static int checkIDNumber(int ID)
{
// Check the number passed in & then loop through all the lines...
// If number is taken then output error, because id exists already
// Else allow the value to be used in the stock system.
int IDNumber = ID;
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
string lineValues;
// In general, you shouldn't explicitly compare to "true" or "false."
// Just write this as "!sr.EndOfStream"
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(IDNumber.ToString()))
{
// In this case, you don't have to bother checking the rest of the file
// since you already know that the ID is taken
Console.WriteLine("Id number is currently already taken.");
}
else
{
// You actually can't return that at this point - you need to check
// the *entire* file before you conclude that it's not a duplicate
return IDNumber;
}
}
}
}
I have created a small project . and here is it:
class Program
{
public static void Main()
{
Console.WriteLine("Welcome");
Console.WriteLine("1 to go to Data Files ");
Console.WriteLine("type quit to exit");
string input = Console.ReadLine();
if (input == "1")
{
Data go = new Data();
}
else if (input == "quit")
{
}
}
}
When user type quit. I want my program to exit. anyone help me, please
You just need something like this:
else if (input == "quit")
{
return;
}
Update: based on your comments I think you're looking for something like this:
class Program
{
public static void Main()
{
while(true)
{
Console.WriteLine("Welcome");
Console.WriteLine("1 to go to Data Files ");
Console.WriteLine("type quit to exit");
string input = Console.ReadLine();
if (input == "1")
{
Data go = new Data();
}
else if (input == "quit")
{
return;
}
else
{
Console.WriteLine("invalid option");
}
}
}
}
You just can use Environment.Exit(code). where code is integer representation of standard application-exit-codes like return 0 or return 1 in world of C++.