system.formatexception in while(true) loop - c#

The subject is a little problem:
Write a program and continuously ask the user to enter a number or "ok" to exit. Calculate the sum of all the previously entered numbers and display it on the console.
Here is my code:
var sum = 0;
while (true)
{
Console.WriteLine("Enter a number or ok to exit:");
if (Console.ReadLine() == "ok") break;
sum += Convert.ToInt32(Console.ReadLine());
Console.WriteLine(sum);
}
When I tap ok, it terminate.
When I tap number and enter, it shows system.formatexception:The input string is not in the correct format.
I know one of the solution is
var sum = 0;
while (true)
{
Console.Write("Enter a number (or 'ok' to exit): ");
var input = Console.ReadLine();
if (input.ToLower() == "ok")
break;
sum += Convert.ToInt32(input);
}
Console.WriteLine("Sum of all numbers is: " + sum);
Maybe My code looks a little weired, But Why is my code wrong?

Reason is input will be "ok". Can not convert that into an integer.
first you have to store the first input value into other variable.
then convert that string into integer and get summation.
var sum = 0;
while (true)
{
Console.Write("Enter a number (or 'ok' to exit): ");
var input = Console.ReadLine();
int newVariable = 0;
if (input.ToLower() != "ok")
{
newVariable = Convert.ToInt32(input);
}
input = Console.ReadLine();
if (input.ToLower() == "ok"){
break;
sum += newVariable;
}
}
Console.WriteLine("Sum of all numbers is: " + sum);
If there any problem here please let me know.

Try this:
var sum = 0;
while (true)
{
Console.WriteLine("Enter a number or ok to exit:");
String ans = Console.ReadLine();
if (ans == "ok" || ans.ToLower() == "ok") break;
sum += Convert.ToInt32(ans);
Console.WriteLine(sum);
}
Here I've just store input entered by user in one variable and use that variable in further process.
In your first code you have take input two times, first one is in IF condition and second in parsing, that may cause the problem.

The correct way to do this is to use int.TryParse for your conversion from a string to a number. TryParse attempts to convert the string to a number, but if it cannot do so (for example, the string contains more than just numeric digits) it will fail gracefully instead of causing an exception. The other answers so far will all cause an unhandled FormatException if something non-numeric is entered other than "ok". By using int.TryParse you can handle the case where it's a valid number, as well as the case where it is invalid, and then alert the user. Here's an example within the context of your code:
// I prefer using concrete types for numbers like this, so if anyone else
// reads it they know the exact type and numeric limits of that type.
int sum = 0;
int enteredNumber = 0;
while (true)
{
Console.Write("Enter a number (or 'ok' to exit): ");
var consoleInput = Console.ReadLine();
if (consoleInput.ToLower() == "ok")
break;
if(int.TryParse(consoleInput, out enteredNumber))
{
sum += enteredNumber;
}
else
{
Console.WriteLine("You entered '" + consoleInput + "', which is not a number.");
}
}
Console.WriteLine("Sum of all numbers is: " + sum.ToString());
This is better because you know you have no control over the user's input other than to validate it yourself, and so it's better to speculatively convert the number and be alerted to success or failure without triggering an exception. Wrapping everything with a try/catch block is not a proper solution.

Your first code example, as rightly pointed out in the comments, reads a line, tests it for 'ok', then throws it away, reads another line, and uses that to add to the sum, which is not what you wanted.
After some quick research, I would say the most concise way to handle this in C# is probably something like your second code example. In F# I was able to come up with the following examples (one is a loop, the other uses sequences, i.e. IEnumerable<_>s) but I found no concise way to get the same with C# and LINQ…
let inputLoop () =
let rec aux sum =
match stdin.ReadLine () with
| "ok" -> sum
| s -> aux (sum + int s)
stdout.WriteLine (aux 0 |> string)
let inputSeq () =
fun _ -> stdin.ReadLine ()
|> Seq.initInfinite
|> Seq.takeWhile (fun s -> s <> "ok")
|> Seq.sumBy int
|> string
|> stdout.WriteLine

Try it :)
var sum = 0;
while (true)
{
Console.Write("Enter a number: or ok to exit : ");
String input = Console.ReadLine();
if (input == "ok" || input.ToLower() == "ok") break;
if(string.IsNullOrWhiteSpace(input))
continue;
sum += Convert.ToInt32(input);
}
Console.WriteLine("Total Result: " + sum);
Write a program and continuously ask the user to enter a number or "ok" to exit. Calculate the sum of all the previously entered numbers and display it on the console. Happy Coding

var sum = 0;
while (true)
{
Console.Write("Write number or write \"ok\" for exit: ");
var input = Console.ReadLine();
if (input.ToLower() != "ok")
{
sum += Convert.ToInt32(input);
continue;
}
break;
}
Console.WriteLine("All sum: " + sum + ".");

This is one way to do it. I'm just learning to do this!
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter number to know the sum or press ok to exit and display the sum");
int sum = 0;
while (true) // to run the program continously asking user input
{
Console.WriteLine("Enter Number: ");
var input = Console.ReadLine(); // takes user input
if (input.ToLower() == "ok") // compares user input to string ok
break; //if user input is ok, breaks the loop and sum is displayed
var inputInInt = Convert.ToInt32(input); // if user input is int, continues to convert it to integer
sum += inputInInt; // user input in interger is added to sum
}
Console.WriteLine("The sum of entered numbers is: " + sum);
Console.ReadLine();
}
}

Related

How to prevent input of null enter in C# [duplicate]

This question already has answers here:
check for valid number input - console application
(5 answers)
Allow To Only Input A Number - C#
(1 answer)
Closed 2 years ago.
I have just started a table programme. I am just a trainee learning C# from internet, so I am not so good in this.
I just wanted the programme to run according to the user. I want that if the user hits enter simply, the programme should not crash. That is I just wanted to know how to prevent null enter. This is the code is used:
The "______" which used if for writing a line
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace tables
{
class Program
{
static void Main(string[] args)
{
goto found;
found:
Console.WriteLine("");
string textToEnter = "MULTIPLATION TABLES";
Console.WriteLine(String.Format("{0," + ((Console.WindowWidth / 2) + (textToEnter.Length / 2)) + "}", textToEnter));
Console.WriteLine("");
Console.WriteLine("________________________________________________________________________________");
Console.WriteLine("");
int num, j, i;
Console.Write("enter the number of which table u need ? :- ");
num = Convert.ToInt32( Console.ReadLine());
while (num == 0)
{
Console.WriteLine("please enter a valid input");
Console.Write("enter the number of which table u need ? :- ");
num = Convert.ToInt32(Console.ReadLine());
}
Console.Write("enter the number till which the table need to be ? :- ");
j = Convert.ToInt32(Console.ReadLine());
while (j == 0)
{
Console.WriteLine("please enter a valid input");
Console.Write("enter the number till which the table need to be ? :- ");
j = Convert.ToInt32(Console.ReadLine());
}
i = Convert.ToInt32(j);
for (j=1; ; j++)
{
if (j > i)
{
break;
}
Console.WriteLine(num + " * " + j + " = " + num * j);
}
string str;
Console.Write("do you want to continue? (y/n) :- " );
str= Console.ReadLine();
foreach (char ch in str)
{
if (ch == 'y')
{
goto found;
}
else if (ch=='n' )
{
Console.WriteLine("");
Console.WriteLine("THANK YOU FOR USING MY PRODUCT");
}
else
{
Console.WriteLine("please enter a valid input");
}
}
Console.ReadKey();
}
}
}
As suggested in the comments, I'd use int.TryParse(), but inside a do...while() loop. Use a separate flag (boolean) to track whether the user should keep trying again:
bool invalid;
int num, j, i;
do
{
invalid = true;
Console.Write("enter the number of which table u need ? :- ");
String response = Console.ReadLine();
if (int.TryParse(response, out num))
{
invalid = false;
}
else
{
Console.WriteLine("Invalid input. Please try again.");
}
} while (invalid);
// ...repeat the above do...while() block for "j" and "i"...
When you're accepting user input, it's important to perform validation on it. You can't assume that the user will always enter correctly formatted data that your program will be able to work with. As you discovered, a user who hits enter will give you an empty string (""), which can't be parsed to anything.
C# has several ways of attempting parsing. The first, which you're using, is Convert.ToInt32(), which throws an exception if the input it receives is not, in fact, a number. You have to catch the exception with a try/catch block, like so:
try
{
num = Convert.ToInt32(Console.ReadLine());
}
catch(FormatException ex)
{
Console.WriteLine("You didn't enter a proper number!");
}
However, in general, exceptions should be, well, exceptional. They should only be relied upon when rare failures occur, because unwinding the call stack can be expensive.
I would argue that C# has a better method for you to use in this instance: Int32.TryParse()
You can see the documentation here.
TryParse takes two parameters, the thing you're trying to parse (convert), and then a number to store the value in. It returns true or false, indicating if it succeeded or failed in converting the number.
You might use it like this:
var success = Int32.TryParse(Console.ReadLine(), num);
if (success)
{
// do something with 'num' -- it has a valid value now.
}
else
{
// Warn the user, perhaps prompt them to try again
Console.WriteLine("That wasn't a valid number!");
}
You can use a methode to get a safe int value:
private static int ReadIntValue(string psMessage)
{
int lnInt;
string lsValue = string.Empty;
do
{
Console.Write(psMessage);
lsValue = Console.ReadLine();
} while (!int.TryParse(lsValue, out lnInt));
return lnInt;
}
And then use this:
num = ReadIntValue("enter the number of which table u need ? :- ");

c# Need help trying to put in and run two loops for the same input

I've put in a loop with Try.Parse so that if the user enters a decimal number, the program will ask them to enter another number until they put in a integer and then the program will carry on with the next part.
However what i'm struggling with is putting in another loop that makes it so that the user can only enter a number between 1 and 100, and if they don't there should be an error message that loops until they do enter this. Id like them to run at the same time and i have this one, but i want it to also check whether its in the range and i'm not sure how to do that.
I'm new to programming so I'm not great at this.
Thank you in advance!
string inputcost;
string inputmoney;
int validcost;
int validmoney;
int changereq;
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
bool result = int.TryParse(inputcost, out validcost);
while (!int.TryParse(inputcost, out validcost))
{
if (result == true)
{
Console.Write("Valid Value");
}
if (result == false)
{
Console.Write("Please Enter A Valid Integer Value");
Console.WriteLine();
inputcost = Console.ReadLine();
}
}
Your problem here is that the result variable you're looking at is only written once: outside the loop. Consider trying something like the following pseudocode (a do-while loop works exactly the same as a while loop, except it always gets executed once before the condition is checked):
bool validInput;
do
{
// If you set it true to begin with, you can set it false on any unmet conditions
// If it doesn't get set false, you've got a valid input and can exit the loop.
validInput = true;
Read input from user
Check if it's a valid integer, if not print message and validInput = false
Check if it's between 1-100, if not print message and validInput = false;
} while (!validInput);
Then if you want to tackle something more advanced, look at the continue keyword.
Try something like this.
string inputcost;
string inputmoney;
int validcost;
int validmoney;
int changereq;
while (true)
{
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
if (!(valuecost >=1 && valuecost <=100))
{
Console.Write("Please enter value between 1 and 100.");
}
bool result = int.TryParse(inputcost, out validcost);
if (result == true)
{
Console.Write("Valid Value");
}
if (result == false)
{
Console.Write("Please Enter A Valid Integer Value");
}
}
It would be useful to use a method and do something like:
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
bool result = false;
while (!result)
{
result = checkNumber();
}
public static bool checkNumber()
{
if(inputcost < 1 || inputcost > 100)
{
Console.Write("Please Enter a valid value: ");
inputcost = Console.ReadLine();
return false;
}
else
return true;
}
Hope this helps.
string inputcost;
string inputmoney;
int validcost = 0;
int validmoney = 0;
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
// only accept integers
while (!int.TryParse(inputcost, out validcost))
{
Console.Write("Please Enter An Integer Value: ");
inputcost = Console.ReadLine();
}
// valid integer input in variable validcost
bool done = false;
while (!done)
{
Console.Write("Enter an integer between 1 and 100: ");
inputmoney = Console.ReadLine();
if (int.TryParse(inputmoney, out validmoney))
{
if (validmoney > 0 && validmoney < 101)
{
done = true;
}
else
{
Console.WriteLine("Invalid input: " + inputmoney);
}
}
else
{
Console.WriteLine("Invalid input: " + inputmoney);
}
}
//validcost is an integer and validmoney is an integer between 1 and 100
Console.WriteLine("validcost: " + validcost + " validmoney: " + validmoney);
Console.ReadKey();

Validating multiple user input in console application

I'm pretty new to C# and am wondering how I'd go about validating user input to meet the following requirements:
has to be a decimal type. if it isn't it should ask the user to enter a decimal value. (Which i believe i have covered in my code below)
also has to be within a specific range (1 - 1,000,000). If it isn't it should ask the user to enter a number within the correct range
What's the most efficient way of doing this considering i will have multiple user input to validate in the same sort of way.
decimal balance;
Console.Write("Starting Balance: $");
while (!decimal.TryParse(Console.ReadLine(), out balance))
{
Console.Write("Please enter a valid decimal value: $");
}
EDITED BELOW
How about this?
decimal balance;
Console.Write("Starting Balance: $");
while(true)
{
if (!decimal.TryParse(Console.ReadLine(), out balance))
Console.Write("Please enter a valid decimal value: $");
else if (balance < 1 || balance > 100)
Console.Write("Please enter an amount between 1 and 100: ");
else
break;
}
Console.WriteLine("Balance entered is: " + balance.ToString("n"));
return val; line gave me an error so i left it out but the above seems to work?
I'd try something like:
decimal GetUserInput(string inputQuery, decimal min, decimal max)
{
Console.Write(inputQuery);
decimal val;
while(true)
{
if(!decimal.TryParse(Console.ReadLine(), out val))
Console.Write("Please enter a valid decimal value: $");
else if(val < min || val > max)
Console.Write("Please enter an amount between " + min + " and " + max + ": $");
else // the value is a decimal AND it's correct
break;
}
return val;
}
Then use it like:
var startingBalance = GetUserInput("Starting Balance: $", 1, 100000);
var endingBalance = GetUserInput("Ending Balance: $", 1, 100000);
//...
If your min and max are fixed, then you could not pass them as arguments and use a fixed check. And you could also avoid having the query : $ passed in if needed, but I'll leave that to you
Update
The reason why the return val line was giving you an error was because you were inlining it (probably in a void returning function). What I was doing was making a function since you specified it needed to be reusable.
So in your program, you need to make a separate function... your program would look something like this:
class Program
{
// We're declaring this function static so you can use it without an instance of the class
// This is a function, so it can be called multiple times, with different arguments
static decimal GetUserInput(string inputQuery, decimal min, decimal max)
{
// Write the argument "inputQuery" to console
Console.Write(inputQuery);
decimal val;
// Loop indefinitely
while(true)
{
// Read from console into a decimal "val"
if(!decimal.TryParse(Console.ReadLine(), out val))
// It was not a correct decimal, so write the prompt
Console.Write("Please enter a valid decimal value: $");
// It was a correct decimal
else if(val < min || val > max)
// But not in range, so write a different prompt
Console.Write("Please enter an amount between " + min + " and " + max + ": $");
// It was a decimal and within range
else
// so we break the infinite loop and exit after the "}"
break;
// If we have got to this point (we didn't hit the "break"),
// it was either not a decimal or it wasn't within range,
// so it'll loop again and ask for a value from console again.
// The prompt was already written above (in the "ifs")
}
// We got out of the while(true){} loop, so it means we hit "break"
// above, and that means "val" contains a correct value (decimal and
// within range), so we return it to the caller
return val;
}
static void Main()
{
// Your original code went here, but see how my function is *outside* function Main()
// You use my function (GetUserInput) here:
var startingBalance = GetUserInput("Starting Balance: $", 1, 100000);
var endingBalance = GetUserInput("Ending Balance: $", 1, 100000);
// Then with the returned values (stored in "startingBalance"
// and "endBalance"), you can do what you want:
Console.WriteLine("Starting balance was: " + startingBalance.ToString("n"));
}
}
I've made a fiddle with the whole program so you can test online and make changes: https://dotnetfiddle.net/HiwwIP
If I were you, I would do such:
bool isInvalid, isOutOfRange;
decimal balance = 0;
isOutOfRange = true;
do
{
string input = Console.ReadLine();
isInvalid = !Decimal.TryParse(input, out balance);
if (!isInvalid)
{
// use balance<=1 if 1 should not be included
// use balance>=1000000 if 1000000 should not be included
isOutOfRange = (balance < 1 || balance > 1000000);
}
if (isInvalid)
{
Console.WriteLine("Please enter a valid decimal value: $");
}
else if (isOutOfRange)
{
Console.WriteLine("Please enter value between 1 and 1000000: $");
}
} while (isInvalid || isOutOfRange);
Console.WriteLine("{0}, That is a valid value!", balance.ToString());
Console.ReadKey();
Of course you can shortcut by eliminating bool definitions and directly calling functions instead; but I wrote in detail for clarity as you indicated that you are "pretty new".

C# input has to be 5 digits

I have a question that asks the user to enter a student number, how can I make it so it will only accept a 5 digit number. The input is being added to an object like
console.writeline("Enter the student number: ");
then
studentObject.StudentNumber = int.Parse(Console.Readline());
I've tried using
if (Console.ReadLine().Length != 5)
{
//Do this
}
else
{
//Do this
}
But it won't work, the .Length says can't convert type int to bool. I'm stuck, any help please?
You can use regular expressions:
String input;
do {
Console.WriteLine("Please enter student number:");
input = Console.ReadLine();
}
while (!Regex.IsMatch(input, #"^\d{5}$")); // <- five digits expected
// input contains 5 digit string
int number = int.Parse(number);
P.S. In case that the input should be "five digit number, not starting with zero" the regular expression has to be changed to something like that:
while (!Regex.IsMatch("12345", #"^[1-9]\d{4}$")); // five digits, not zero-starting
Probably not the answer to your question, however one thing I noticed:
if you are using Console.Readline() in your if-statement and then want to store it in the studentObject you will need to store it in a variable first. Calling Console.Readline(); again to store it in the studentObject will cause another input to be expected, which nullifies your attempt to validate the input.
Something like this:
static void Main(string[] args)
{
Console.WriteLine("Please enter student number:");
//get the user input
var number = Console.ReadLine();
if (number.Length != 5)
{
Console.WriteLine("Invalid format.");
}
else
{
Console.WriteLine("Yay it works");
}
Console.ReadLine();
}
var input = Console.ReadLine();
int i;
if (input.Length > 0 && input.Length < 6 && Int32.TryParse(input, out i))
// i has 5 digit;
else
// i has zero
char[] cc = Console.Read().ToString().ToCharArray();
if (char.IsDigit(cc[0])&&
char.IsDigit(cc[1])&&
char.IsDigit(cc[2])&&
char.IsDigit(cc[3])&&
char.IsDigit(cc[4]))
{
//Life's GOOD!
}else { //bad input}
Note: I'm self-taught & don't have much knowledge. Correct me if wrong.

Please help i have got very confused with the if statement below

I want the user to input a number, but if it is below zero I would like to show an error message and then loop round and ask the user for another number. Here is the code I have at the moment.
// this determines what the loop does.
for (int CustPos = 0; CustPos < LineNum; CustPos = CustPos + 1)
{
// this asks the user to enter the sales figures
Console.Write("enter sales figures for" + customer[CustPos] + " ");
// this is user's input is read in and stored.
sales_figures[CustPos] = Double.Parse(Console.ReadLine());
if (sales_figures[CustPos] < MIN_SALES_FIGURE) //True - continue
{
Console.WriteLine("");
Console.WriteLine("entry invalid");
Console.WriteLine("enter another value");
}
else//FALSE -> Go back to start of loop
{
Console.WriteLine("");
}
//this section displays the cust name, sales figure 70/30.
Console.WriteLine(" ");
fee_payable[CustPos] = (sales_figures[CustPos] / 100.0)
* licence_fee_in_percent[CustPos];
Console.WriteLine(customer[CustPos] +
" ----------- " + fee_payable[CustPos]);
Console.WriteLine("Licence fee to be paid in GBP is :" +
fee_payable[CustPos]);
seventy_percent_value = ((fee_payable[CustPos] / 10.0) * 7);
Console.WriteLine("70 percent of this fee is" +
seventy_percent_value);
thirty_percent_value = ((fee_payable[CustPos] / 10.0) * 3);
Console.WriteLine("30 percent of this fee is" +
thirty_percent_value);
Console.WriteLine(" ");
}
. Please help all advice will be greatly appreciated!
Thanks
I think a do-while loop would be better here, pseudocode:
userInput = -1
do
{
userInput = Console.ReadLine
}
while (userInput <0)
Colin E.
Youre on the right track, just look at the keyword Continue
This is the example in the link:
using System;
class ContinueTest
{
static void Main()
{
for (int i = 1; i <= 10; i++)
{
if (i < 9)
{
continue;
}
Console.WriteLine(i);
}
}
}
Note: The continue statement passes control to the next iteration of the enclosing iteration statement in which it appears.
if (sales_figures[CustPos] < MIN_SALES_FIGURE) //True - Continue //FALSE -> Go back to start of loop
You don't actually have any code here to make it go back to the start of the loop.
I recommend that you write it all out as pseudocode first, then turn it into code:
if (number entered is too low)
then restart loop
otherwise carry on
Instead of an if, you'll want a while:
while( sales_figure[CustPos] < 0 )
{
Console.Write("enter sales figures for" + customer[CustPos] + " ");
sales_figures[CustPos] = Double.Parse(Console.ReadLine());
}
Which guarantees that it will keep prompting until they enter something greater than zero.
Continue, does NOT do what you want it to. Continue means, "move on and ignore this iteration" which means you'd have an incorrect value for that customer.
Use a WHILE loop in combination with your IF:
continueflag = 0;
while (continueflag == 0)
{
sales_figures[CustPos] = Double.Parse(Console.ReadLine());
Console.WriteLine("");
if (sales_figures[CustPos] >= MIN_SALES_FIGURE) {
Console.WriteLine("entry invalid");
Console.WriteLine("enter another value");
} else continueflag = 1;
}

Categories

Resources