Converting Strings to Ints - c#

Alright, nub question. I know. Basic response might be
Convert.ToInt32(string);
But naturally, C# does every natural process to make sure just that doesn't happen.
Here's my code:
while (true)
{
while (true)
{
//ask for time
Console.WriteLine("What is the hour?");
Console.WriteLine();
string s = Console.ReadLine();
//convert input to int
YourTime.nHour = Convert.ToInt32(s);
//check to see if it's legal
if ((YourTime.nHour <= 12) || (YourTime.nHour > 0))
{
break;
}
//etc etc code
}
}
I want to make sure the input is an actual hour. When I run this code, it always labels the if() statement as "true" and breaks, even if I inputted something like -13 or 99.
I'm sure there's a simple replacement for "Convert.ToInt32(s);", but to be honest it seems like I've tried everything. I decided it would be best to follow step-by-step instructions from people who are aware of the code at hand.
[EDIT] - Wrong operator, not the conversion. Thanks to everyone who helped!

You need to use AND not OR. So, change it to
if ((YourTime.nHour <= 12) && (YourTime.nHour > 0))

It's your if statement that's invalid, not the Convert.ToInt32
if ((YourTime.nHour <= 12) || (YourTime.nHour > 0)) will always be true. I think you meant to do if ((YourTime.nHour <= 12) && (YourTime.nHour > 0))

Do you mean no matter what integer you type in it always breaks?
If so its because no matter what integer you type in it will always pass one of those conditions.
i.e If I entered 10000000, it would still be greater than 0
and if I entered -10000000 it would still be less than 12

You just mixing two things that should not be mixed.
Converter from string to int should not have any business logic incorporated, that is model responsibility to know that this field is actually hours and not payment amount due
So to separate it you can use many things, for example data annotations, take a look at following code
public class MyTime
{
[Require]
[Range(0, 12, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
public int Hours { get; set; }
[Require]
[Range(0, 59, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
public int Minutes { get; set; }
}
this way you have model defined which can be validated against rules it knows about and you can get error message that has sense
PS this link can show you how to create custom validator if you are using data annotations outside asp.net mvc

Related

Trouble with generic method

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).

Validate user input with multiple criteria c#

I need to validate input based on whether or not it's a number and whether or not it exceeds inventory levels.
So far I can check for inventory level, but I only know how to use tryparse to check if its a number, and I don't want to output anything. Here's what I have so far. It gives an error because I didn't give it a variable.
if (ckbSingle.IsChecked.Value)
{
if (int.TryParse(txtSingQuan.Text, out Convert.ToInt32(txtSingQuan.Text)))
if ((singleespresso.DunkinInventory - Convert.ToInt32(txtSingQuan.Text)) <= 0)
{
MessageBox.Show("Espresso low in stock.");
}
else
{
ProductList.Add("Single Espresso");
}
}
I want it to allow me to continue with the code if the input is appropriate and show a message box if it's not.
It gives an error because I didn't give it a variable
Then give it one:
if (ckbSingle.IsChecked.Value)
{
if (int.TryParse(txtSingQuan.Text, out int qty) && qty >= singleespresso.DunkinInventory)
{
// Input is a valid number and is greater than or equals to stock
ProductList.Add("Single Espresso");
// qty variable is accessible in that scope if need be
}
else
{
// Input is either not a number or lower than stock
MessageBox.Show("Espresso low in stock.");
}
}

Check if input has number and string to calculate in C#

I am really into the basics of programming and while writing a few lines of code to convert Celsius to Fahrenheit, which is pretty easy I started to wonder the following:
Can I make the program show me an answer depending if I wrote in the Console:
25C //to convert to F
or for example 100F // to convert to C
So far my knowledge goes to advanced "if" constructs and "for" cycles. Just started to study "do-while".
I am missing some knowledge how to properly search an input for number && specific char in order to give proper calculation.
I know that it seems a little complicated to make input :
25F // in one line instead of
25
F
but this will expand my knowledge and understanding.
I will try the latter now, should be easy, but can't find out how to do the former.
Thanks in advance!
Darin
In C# any string is actually a class, which contains useful methods for example:
string input = "25F";
if (input.EndsWith("F"))
{
// handle Fahrenheit
}
Then you can get rid of the last character like so:
string inputWithoutLastCharacter = input.Substring(0, input.Length - 1);
To convert a string to a number you can:
try
{
int number = int.Parse(inputWithoutLastCharacter);
}
catch (Exception ex)
{
Console.WriteLine("Could not convert your input to a number " + ex.ToString());
}
Try/catch is there to handle error cases where the input is not a valid number.
Also check out other methods of string. For example ToLower() to handle both "f" and "F".
Good luck.
String temp = Console.ReadLine();
char scale = temp[temp.Length-1];
if(temp.ToUpper().Contains("F")) {
int temperature = Int32.Parse(temp.Remove(temp.Length-1,1));
double celciusValueOfTemp = (temperature-32)/1.8;
Console.WriteLine(celciusValueOfTemp);
}
else if(temp.ToUpper().Contains("C")) {
int temperature = Int32.Parse(temp.Remove(temp.Length-1,1));
double fahrenheitValueOfTemp = temperature*1.8+32;
Console.WriteLine(fahrenheitValueOfTemp);
}

C#- Getting user input for Age.. but receiving error?

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.

C# dealing with invalid user input

Have a simple console app where user is asked for several values to input. Input is read via console.readline(). Ex
Name: Fred //string
Lastname: Ashcloud //string
Age: 28 //int
I would like to make sure that int and double types are entered and if the user enters garbage, lets him repeat the procedure.
Example, if the user enters "28 years old" where age expects int the app will crash. What is the best way to check for these inputs?
Right now I can only think of:
while (!Int32.TryParse(text, out number))
{
Console.WriteLine("Error write only numbers");
text = Console.ReadLine();
}
Is there any other way to do this? try catch statements if one wants to give a more detailed feedback to the user? How in that case?
For a console application, your code is perfectly fine.
However, you might want to abstract that into a reusable function so that you can read different numbers without repeating the code.
Also, you might want to provide some way for the user to cancel.
using System.Text.RegularExpressions;
int GetNumberFromString( string str_age )
{
Regex number = new Regex("[0-9][0-9]?");
Match n = number.Match(str_age);
if (n.Value != "")
return System.Convert.ToInt16(n.Value, 10);
else
return -1;
}
This will parse any data out besides the age or return -1 if no age is present.
this also assumes age 0-99.
Actually, your code is good. I would add negative number check, and perhaps huge number check too.
Regular Expressions are good.
Regex age = new Regex(#"^[0-9]*$");
while (!age.match(age_from_console)) {
Console.WriteLine("Age Invalid, try again ->");
}

Categories

Resources