I am trying to write a simple program that asks the user to enter a number and then I will use that number to decide what the cost of the ticket will be for their given age. I am having trouble when trying to convert the string to int. Otherwise the program layout is fine. Any suggestions?
thanks
using System;
class ticketPrice
{
public static void Main(String[] args)
{
Console.WriteLine("Please Enter Your Age");
int input = Console.ReadLine();
if (input < 5)
{
Console.WriteLine("You are "+input+" and the admisson is FREE!");
}
else if (input > 4 & input < 18)
{
Console.WriteLine("You are "+input+" and the admission is $5");
}
else if (input > 17 & input < 56)
{
Console.WriteLine("You are "+input+" and the admission is $10");
}
else if (input > 55)
{
Console.WriteLine("You are "+input+" and the admission is $8");
}
}
}
Try the int.TryParse(...) method. It doesn't throw an exception.
http://msdn.microsoft.com/en-us/library/f02979c7.aspx
Also, you should use && not & in your conditions. && is logical AND and & is bitwise AND.
For easy parsing of strings to integers (and other number types), use that number type's .TryParse(inputstring, yourintegervariable) method. This method will output a Boolean (True/False), letting you know whether the operation passed or failed. If the result is false, you can give an error message before going any further (don't have to worry about crashing your program).
Previous text concerning switch statements has been removed
In C#, you need to use the && operator for logical AND. & is not the same and may not work the way you believe it will.
I suggest to use the Int32.TryParse() method. Further I suggest to refactor your code - you can make it much cleaner (assuming this is not just example code). One solution is to use a key value pair list to map from age to admission.
using System;
using System.Collections.Generic;
using System.Linq;
static class TicketPrice
{
private static readonly IList<KeyValuePair<Int32, String>> AgeAdmissionMap =
new List<KeyValuePair<Int32, String>>
{
new KeyValuePair<Int32, String>(0, "FREE!"),
new KeyValuePair<Int32, String>(5, "$5."),
new KeyValuePair<Int32, String>(18, "$10."),
new KeyValuePair<Int32, String>(56, "$8.")
};
public static void Main(String[] args)
{
Console.WriteLine("Please Enter Your Age!");
UInt32 age;
while (!UInt32.TryParse(Console.ReadLine(), out age)) { }
String admission = TicketPrice.AgeAdmissionMap
.OrderByDescending(pair => pair.Key)
.First(pair => pair.Key <= age)
.Value;
Console.WriteLine(String.Format(
"You are {0} and the admission is {1}",
age,
admission));
}
}
I used an unsigned integer to prevent entering negative ages and put the input into a loop. This way the user can correct an invalid input.
int number = int.Parse(Console.ReadLine());
Be aware that this will throw an exception if they enter an invalid number.
The first thing you need to do is change your input variable to a string:
string input = Console.ReadLine();
Once you have that, there are several ways to convert it to an integer. See this answer for more info:
Better way to cast object to int
Related
so I've been assigned a cinema project to complete for college, which involves me taking input of type Int and DateTime. I decided to create a method to speed up the error handling for every single variable that requires checking.
static T CheckInput <T> (string message, string errorMessage, T lowerBound, T higherBound)
{
T input;
do
{
Console.Write(message);
try
{
input = (T)Convert.ChangeType(Console.ReadLine(), typeof(T));
}
catch
{
input = lowerBound;
}
if (input > higherBound || input < lowerBound) Console.Write(errorMessage);
} while (input > higherBound || input < lowerBound);
return input;
}
This should technically allow me to take input of type int and Datetime, which is all I need it to do. However upon running it, the code keeps running until the datetime is valid andthen just continues the while loop without printing the user's ticket.
while (true)
{
// Print List of films
Console.Write("Welcome to Aquinas Multiplex\nWe are currently showing:\n");
for (int i = 0; i < films.Length; i++)
{
Console.Write("{0}. {1} ({2})\n", i + 1, films[i], filmAges[i]);
}
// Error checking for film and age input
filmToSee = CheckInput<int>("Please enter the number of the film you want to see: ", "That is not a valid film\n", 1, films.Length);
age = CheckInput<int>("Please enter your age: "," Not a valid age!\n", 1, 101);
// Age check
if (age < filmAges[filmToSee - 1])
{
Console.Write("ACCES DENIED - TOO YOUNG!\n(Press any key to proceed back to homepage)");
Console.ReadKey();
Console.Clear();
continue;
}
bookDate = CheckInput<DateTime>("Please enter the date you wish to see the film (must be no longer than a week in advance): ", "Not a valid date!\n",DateTime.Now.Date, DateTime.Now.Date.AddDays(7));
Console.Clear();
Console.Write("Your ticket:\n\n--------------------\nAquinas Multiplex\nFilm : {0}\nDate : {1}\n\nEnjoy the film!\n--------------------\n\n(Press any key to go back to the main menu)", films[filmToSee-1], bookDate.Date);
Console.ReadKey();
Console.Clear();
}
What is wrong with the code? I don't see anything in the while loop that would stop the final few lines and I have tried multiple ways to get the generic to output correctly. (Inputting an int to it works as intended, it's just not working for DateTime).
Go back to basics and add Exception handling. Wrap in try catch blocks and write the exception to console. It is important to always apply best practices. Also remember to leverage off the debugger built into your IDE and step through your code to see what it does, and what exceptions are thrown.
You will get a compilation error here:
if (input > higherBound || input < lowerBound) Console.Write(errorMessage);
So, I am not sure how this is running? You cannot compare greatness between T and T they are constrained to type IComparable<T>. Then you can use T.CompareTo(T). Refer to the where (generic type constraint).
I've been trying to find a way to do this but not had much luck so far.
Basically what I'm trying to do is limit the entries from the user so they can only enter 1 letter and 1 number using the Console.Readkey. So, for example, A1, E5, J9 etc. I want to avoid them entering like 55 or EE as this causes an error in my code. Is there an easy way to achieve this?
You need to write your own logic like you will check on every input value contains at least 1 number and 1 letter is true else false:
string value = Console.ReadLine();
//you can also check value.length and redirect if length greater than 2
if (value.Length > 2)
{
Console.WriteLine("Please enter correct value");
return;
}
if (value.Contains("Your Number"))
{
if (value.Contains("Your Letter"))
{
//your code goes here
}
else
{
Console.WriteLine("Please Enter Correct Value");
}
}
else
{
Console.WriteLine("Please Enter Correct Value");
}
This uses a GetChar method which requires that you pass a function to check whether the input is a character or a number. It won't allow you so proceed until a valid entry has been made.
using System;
class Program {
public static void Main (string[] args) {
string value = string.Empty;
// Get a character, using char.IsLetter as the checking function...
GetChar(ref value, char.IsLetter);
// Get a number, using char.isNumber as the checking function...
GetChar(ref value, char.IsNumber);
Console.WriteLine($"\nValue: {value.ToUpper()}");
}
// Get a character and append it to the referenced string.
// check requires that you pass a function reference for the required check.
public static void GetChar(ref string value, Func<char, bool> check) {
// Loop until the check passes.
while(true) {
char key = Console.ReadKey(true).KeyChar;
// If check passes...
if(check(key)) {
// Append the value
value += key.ToString().ToUpper();
// Print it...
Console.Write(key.ToString().ToUpper());
// Break out of the loop.
break;
}
}
}
}
I'm trying to make a program that takes a number and print it on screen but if the user press enter the code ask the user to enter the number again but instead it shows me a exception
Enter_No:
Console.WriteLine("enter number");
int? n = Convert.ToInt32(Console.ReadLine());
if (n == (int?)null)
{
goto Enter_No;
}
else
{
Console.WriteLine(n);
}
Use int.TryParse:
int? num = null;
while(!num.HasValue)
{
Console.WriteLine("Please enter an integer:");
num = int.TryParse(Console.ReadLine(), out int i) ? i : new int?();
}
Console.WriteLine("Entered integer: " + num.Value);
Tim's solution is wonderfully compact. Here's why your attempt failed.
From MSDN, Convert.ToInt32() throws a FormatException if:
value does not consist of an optional sign followed by a sequence of digits (0 through 9).
The preferred approach is int.TryParse(), as it returns false if it's unable to parse the integer rather than throwing an exception.
While the goto keyword is supported in C#, there are few or no situations (depending on who you ask) where it's the best option for flow control. Tim's while loop is an excellent approach.
First, don't use Go To:
Second: Inspect your data and use tryparse:
bool success = false;
do
{
Console.WriteLine("enter number");
var n = Console.ReadLine();
if (n == null)
{
// goto Enter_No;
}
else
{
int typedNum;
success = int.TryParse(n, out typedNum);
Console.WriteLine(typedNum);
}
} while (!success);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
So i am learning C# now, I have tried C++ and Java ( i liked Java more than C++ I still do not fully understand C++) and now i'm giving C# a try. I did another little program that displayed my age, date and time, favorite color, etc, basically it was mostly strings, no int. I want to be able to enter any number in the GrossIncome but be within a range, not just have it set to a specific number,but everything that I could think of to use, visual studio does not like, I have watched some tutorial on pluralsight but none seem to show an example of it.
//My first program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Week1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Here is my program, enter your name to continue");
string name = Console.ReadLine();
Console.WriteLine("Hello, " + name);
Console.WriteLine("enter your address");
string address = Console.ReadLine();
Console.WriteLine(address);
Console.WriteLine("enter your monthly income");
int GrossMonthlyPay = 10000; //here is where i need to have the option to enter any different value like i.e. >0 <10000
Console.WriteLine(GrossMonthlyPay);
Console.WriteLine("your tax deduction set at 7% are ");
double taxes = (0.07);
Console.WriteLine(taxes = GrossMonthlyPay * taxes);
Console.Write("\nPress any key to continue...");
Console.ReadLine();
}
}
}
Neither c# nor the .Net framework have a built in type for range.
There are several options, though:
Use a Tuple (and in c# 7.0 or higher, ValueTuple)
Create an immutable struct with the int properties for From and To
Create your own class with int properties for From and To
Use an array with 2 int values
Use an anonymous type
I would recommend using a ValueTuple if you are working with c# 7.0 or higher.
If you are working with a lower version of c#, I would recommend creating an immutable struct. I would not recommend using any collection type (e.g array, list etc') nor would I recommend using a Tuple or an anonymous type.
It all boils down to code readability. If you are using value tuples or creating your own type, you can set the names of the properties.
With System.Tuple you can only use the built in Item1 and Item2 which clutters your code.
For c# 6, I would probably create a struct to represent a range:
(for lower versions of c# you need to change a few things such as the usage of string interpolation and getters only auto-implemented properties, but still an immutable struct is probably the best option)
public struct Range
{
public Range(int from, int to)
: this()
{
From = from;
To = to;
}
public int From { get; }
public int To { get; }
public override string ToString()
{
return $"{From} - {To}";
}
}
And you can create it with a console application like this:
public static void Main()
{
Console.WriteLine("Enter salary range:");
var low = GetIntFromUser("From:", "value must be an integer");
var high = GetIntFromUser("To:", "value must be an integer");
var range = new Range(low, high);
Console.WriteLine("Salary entered is {0}", range);
}
public static int GetIntFromUser(string askFor, string error)
{
int result = 0;
while(true)
{
Console.WriteLine(askFor);
var input = Console.ReadLine();
if(int.TryParse(input, out result))
{
return result;
}
Console.WriteLine(error);
}
}
See a live demo on DotNetFiddle.
Console.ReadLine() only gives you a string, so you have to convert it to int yourself. In case the user did not enter integer or it is out of range, you simply reprompt the user for another value.
int GetIntBetween(int min, int max) //inclusive
{
int result;
string str = Console.ReadLine();
while (true)
{
if (Int32.TryParse(str, out result))
{
if (result >= min && result <= max)
break;
}
Console.WriteLine(String.Format("Only integer between {0} and {1} (inclusive) is allowed, please reenter another value.", min, max));
str = Console.ReadLine();
}
return result;
}
Console.ReadLine() will return string, So when you need to convert string to int when you need to judge the GrossMonthlyPay.
int n;
if ( int.TryParse(GrossMonthlyPay, out n) )
{
// n is int, can judge here
}
You can't in the console. You can just tell the user to reenter a valid loan number, if the last one was out of range. What you want can be done with an UI. There you can restrict the valid numbers. Just need to listen to value changes and than adjust accordingly.
I am trying to make improve my programming and getting things drilled into my head so I'm just quickly developing an application that gets user's input and prints their name. But also gets their input for "Age verification".
I'm practicing IF & ELSE statements as well as nesting classes.
However my compiler is shooting me an error and I just cannot seem to figure it out. I'm trying to get the user to input his age, and then proceed with the IF & ELSE statement.
Compiler is shooting error that . ""Cannot implicitly convert type
string to int"
The only error in the program right now is the
myCharacter.age = Console.ReadLine();
using System;
namespace csharptut
{
class CharPrintName
{
static void Main()
{
Character myCharacter = new Character();
Console.WriteLine("Please enter your name to continue: ");
myCharacter.name = Console.ReadLine();
Console.WriteLine("Hello {0}!", myCharacter.name);
Console.WriteLine("Please enter your age for verification purposes: ");
myCharacter.age = Console.ReadLine();
if (myCharacter.age <= 17)
{
Console.WriteLine("I'm sorry {0}, you're too young to enter!",myCharacter.name);
}
else if (myCharacter.age >= 18)
{
Console.WriteLine("You can enter!");
}
}
}
class Character
{
public string name;
public int age;
}
}
As the error says you can't implicitly type a string to an int. You need to parse it into an int.
string input = Console.ReadLine();
int age;
if (int.TryParse(input, out age)
{
// input is an int
myCharacter.age = age;
}
else
{
// input is not an int
}
You are trying to assign a string value to an int with this line:
myCharacter.age = Console.ReadLine();
Try:
myCharacter.age = Int32.Parse(Console.ReadLine());
character.age expects an Int but ReadLine() returns a string, you need to look at using int.Parse or int.TryParse to avoid exceptions
e.g.
if (!int.TryParse(Console.ReadLine(),out myCharacter.age)) {
Console.WriteLine("You didn't enter a number!!!");
} else if (myCharacter.age <= 17) {
Console.WriteLine("I'm sorry {0}, you're too young to enter!",myCharacter.name);
} else {
Console.WriteLine("You can enter!");
}
This looks like a student project.
The input coming from the ReadLine() is always of type string. You're then comparing a string to 17 which isn't valid, as 17 is an int. Use TryParse versus parse to avoid throwing an exception at runtime.
string typedAge = Console.ReadLine();
int Age = 0;
if (!int.TryParse(typedAge, out Age))
Console.WriteLine("Invalid age");
if (Age <= 17)
Console.WriteLine("You're awfully young.");
OK. The problem here is that the age is defined as an int and Console.ReadLine() always returns a string so thus you have to convert the user input from string to integer in order to correctly store the age.
Something like this:
myCharacter.age = Int32.Parse(Console.ReadLine());
When you read input from the console, it returns it to you in the form of a string. In C#, which is a statically typed language, you cannot simply take one type and apply it to another type. You need to convert it somehow, there are several ways to do this.
The first way would be casting:
myCharacter.age = (int)Console.ReadLine();
This won't work because a string and an integer are two completely different types and you can't simply cast one to the other. Do some reading on casting types for more information.
The second way would be to convert it, again there are a couple of ways to do this:
myCharacter.age = Int32.Parse(Console.ReadLine());
This will work as long as you type in an actual number, in this case the Parse method reads the string and figures out what the appropriate integer is for you. However, if you type in "ABC" instead, you will get an exception because the Parse method doesn't recognize that as an integer. So the better way would be to:
string newAge = Console.ReadLine();
int theAge;
bool success = Int32.TryParse(newAge, out theAge);
if(!success)
Console.WriteLine("Hey! That's not a number!");
else
myCharacter.age = theAge;
In this case the TryParse method tries to parse it, and instead of throwing an exception it tells you it can't parse it (via the return value) and allows you to handle that directly (rather than thru try/catch).
That's a little verbose, but you said you're learning so I thought I'd give you some stuff to consider and read up on.