C# Variable int assumes a different value - c#

I'm trying to create a simple program to calculate an average. The user should enter a positive number, then I create a loop to sum from 0 to the number entered. Then the average is the total divided by the number entered.
Problem: When I enter a number, for example, 10, the variable becomes 58. To any value that I enter, it always adds 48. Anyone have a clue about this issue?
Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace inClass1
{
class Loops
{
static void Main(string[] args)
{
int total = 0;
int num;
Console.Write("Enter a positive number: ");
num = Convert.ToInt32(Console.Read());
for (int i = 0; i <= num; i++)
{
total = total + i;
}
double average = total / (double)num;
Console.WriteLine("The average is = " + average);
Console.ReadLine();
}
}
}

It's because Console.Read method reads the first char and returns its ASCII value. And it only reads one char, so you can't read more than one number at the same time. To fix that just use Console.ReadLine to take a string as input:
um = Convert.ToInt32(Console.ReadLine());
In case where the user inputs an invalid number this will fail. To prevent that you can look into int.TryParse method.

The problem is that you are using Console.Read.
That method returns a int, not a string. That int is the Unicode character code of the read character. The overload of Convert.ToInt32 that takes a int looks like this:
public static int ToInt32(int value) {
return value;
}
(Reference Source)
Which means that its just returning the passed value (instead of parsing). Unicode '1' is the number 49.
Instead, use Console.ReadLine which in addition to getting the whole input (not just the first character) will return a string, so that int.Parse is called on it instead of casting when you use Convert.ToInt32.

Related

I can't figure out why I'm reading wrong input in reading array elements in codechef problem for reverse array problem

I'm getting different user input instead of getting real inputs given by user in codechef
User Input:
4
1 2 3 4
Expected Output:
4 3 2 1
using System;
public class Test
{
public static void Main()
{
int N = Convert.ToInt32(Console.ReadLine());
int[] arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = Convert.ToInt32(Console.Read());
}
for(int j=N-1;j>=0;j--){
Console.Write(arr[j]);
Console.Write(" ");
}
}
}
Output I got:
32 50 32 49
Since you said you want to do it without ReadLine, let's work with your current code. There are two issues at hand.
You should skip the spaces
You get the character codes instead of the values
To skip the spaces, you can simply read them and do nothing with the read character. I implemented this below in a way that assumes after every number (one digit long) there will be a single space to ignore. But you could also do that in a less hacky way by checking what the read character actually is before you discard it.
To get the character code into the value, I first perform a conversion into a char by casting it. Then I get the numeric value, which might be a double. But because you know that your numbers are integers, we can cast that to int.
using System;
class Program {
static void Main(string[] args) {
int N = Convert.ToInt32(Console.ReadLine());
int[] arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = (int)Char.GetNumericValue((char)Console.Read());
Console.Read();
}
for(int j=N-1;j>=0;j--){
Console.Write(arr[j]);
Console.Write(" ");
}
}
}

How do I correctly convert strings to ints and input them into a list?

I'm making a program that asks the user for numbers for as long as he inputs positive values.
Here's the code that I currently have written, but I've not come to complete understanding with the function of and .Parse methods.
using System;
using System.Collections.Generic;
namespace Chapter
{
class Program
{
static void Main()
{
int input;
List<int> numbers = new List<int>();
Console.WriteLine("Input number: ");
input = Convert.ToInt32(Console.ReadLine());
numbers.Add(input);
while (input >= 0)
{
Console.WriteLine("Input number: ");
input = Convert.ToInt32(Console.ReadLine());
int val = Int32.Parse(input);
numbers.Add(val);
}
Console.WriteLine("the numbers you have input are");
foreach (int number in numbers)
{
Console.Write(number + " ");
}
}
}
}
The best way to achieve this is to use the Int32.TryParse method. This allows you to validate the input and handle it accordingly as well as converting to an int.
See the below example:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
int input;
List<int> numbers = new List<int>();
do
{
Console.WriteLine("Input number: ");
while (!Int32.TryParse(Console.ReadLine(), out input))
{
Console.WriteLine("The value entered was not a number, try again.");
Console.WriteLine("Input number: ");
}
if (input >= 0)
numbers.Add(input);
}
while (input >= 0);
Console.WriteLine("the numbers you have input are");
foreach (int number in numbers)
{
Console.Write(number + " ");
}
}
}
Calling Convert.ToInt32(string) or Int32.Parse(string) do nearly the same thing. The difference is that Convert.ToInt32 will return 0 if the input is null and Int32.Parse will throw an exception.
If you were to look at the implementation you will find that Convert.ToInt32 calls Int32.Parse.
Anothing thing to note is that the Convert class allows you to convert a much wider range of types to intergers. The Int32.Parse method only accepts strings.
The issue with your code is in this block:
input = Convert.ToInt32(Console.ReadLine());
int val = Int32.Parse(input);
The input value has already been converted and is now an integer. This cannot be parsed (and doesn't have to be).
When working with user input, I'd rather use int.TryParse (what if user provides "bla-bla-bla"?).
I aslo suggest using infinite loop: keep asking user until (s)he puts negative value (in which case
we break the loop):
List<int> numbers = new List<int>();
// keep reading user input
while (true) {
Console.WriteLine("Input number: ");
// We try parsing (i.e. converting) user input - Console.ReadLine()
// into integer value - number
if (!int.TryParse(Console.ReadLine(), out int number))
// if parsing fails, say, user put "aha!", we let user know it
Console.WriteLine("Not a valid integer number, please, try again");
else if (number < 0)
// if number is negative stop asking user
break;
else
// non-negative numbers are added into the list
numbers.Add(number);
}
Console.WriteLine("the numbers you have input are");
// You can print the list in one go:
Console.Write(string.Join(" ", numbers));
Parseing detail:
int.TryParse(Console.ReadLine(), out int number)
int.TryParse takes user input Console.ReadLine() as an argument and returns true or false whether parsing succeeds or not. In case parsing succeeds, number contains parsed value.

Could someone explain why Converting to int and using read line instead of Read fixed my issue?

So previous I was having a ton of trouble with finding the difference between a randomly generated number and user input. I did a little search and found that I couldn't use Console.Read(); and that I actually had to use this int guess = Convert.ToInt32(Console.ReadLine()); While playing around with it i accidentally made it Convert.ToInt32(Console.Read()); which was in turn making the math completely wrong. Apologies if I'm not explaining myself effectively I'm new to coding and this was meant to be something to learn from. Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Would you like to play the guessing game?");
string input = Console.ReadLine();
if (input.Equals("yes"))
{
Console.WriteLine("Alright! The rules are simple, i'll think of a number and you guess it!");
Console.WriteLine("Alright enter your guess: ");
int guess = Convert.ToInt32(Console.ReadLine());
Random rand = new Random();
int answer = rand.Next(1,11);
if (rand.Equals(guess))
{
Console.WriteLine("Congratulations you guessed correctly!");
}
else
{
Console.WriteLine("Aww you were so close! I guessed " + answer);
int difference = guess - answer;
Console.WriteLine("you were only " + Math.Abs(difference) + " away");
}
} else
{
Console.WriteLine("Closing application...");
Thread.Sleep(1000);
Environment.Exit(0);
}
}
}
}
Console.Read()
Returns you the ascii value of a single character being input.
For example, entering 'A' would return 65. See here for a list of ascii codes. Note that the ascii value for 1 is actually 49.
Convert.ToInt32(Console.ReadLine());
Reads the entire line and tries to convert it to an integer.
Console.Read() will grab just one character and Console.ReadLine() takes the whole line or everything the user types until it found the "Enter" key pressed.
Becuase Console.Read reads in characters from the console. It returns, as an integer. So when you enter "yes" the output will be
121 = y
101 = e
115 = s
13 =
10 =
The final two characters (13 and 10) are equal to the Windows newline.

Random not getting its max value

I am trying to create a console application which is basically a very simple version of a security measure used by some websites and banks etc.
The user will have declared a "Secret Word"(stored in a stringBuilder), after which, every time the user tries to access the program/website etc they have to enter character X of the word (X generated via a random). However, the random never selects the last character of the word.
Example: When i use a 2 letter Secret word, it will only ever select the first letter, when i have tried getting it to select the letter by other methods it thinks that there is a letter 0 which throws the whole application.
Why is the final character never being selected? please help (new to c#)
Code Below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace randomCharSelecter
{
class Program
{
static void Main(string[] args)
{
StringBuilder stringBuilder = new StringBuilder();
Console.WriteLine("Please Enter Your Secret Word");
stringBuilder.Append(Console.ReadLine());
EnterInput:
Random rndSelect = new Random();
int randomChar1 = rndSelect.Next(1, (stringBuilder.Length));
Console.WriteLine("Please enter character {0} of your secret word", randomChar1);
string userInput = Console.ReadLine();
if (userInput == (Convert.ToString(stringBuilder).Substring(randomChar1 - 1, 1)))
Console.WriteLine("Correct!");
else
{
Console.WriteLine("Incorrect! Please try again");
goto EnterInput;
}
Console.ReadLine();
}
}
}
This is the expected behavior. From the documentation:
Return Value
Type: System.Int32
A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned.
In other words if you want a random integer between 1 and stringBuilder.Length, inclusive (that is, that the result could possibly equal stringBuilder.Length), you need to use:
int randomChar1 = rndSelect.Next(1, stringBuilder.Length + 1);
Alternatively, you could simply modify the code to make use of zero-based indexing:
int randomChar1 = rndSelect.Next(0, stringBuilder.Length);
...
if (userInput == (Convert.ToString(stringBuilder).Substring(randomChar1, 1)))
Console.WriteLine("Correct!");
Your problem is that the second value of Random.Next(int val1, int val2) is end-exclusive. So you'll end up having to do stringBuilder.Length + 1
Source: http://msdn.microsoft.com/en-us/library/2dx6wyd4(v=vs.110).aspx

Random number in c# which should be exactly random every time?

i am trying to generate random number for my mental math quiz game. But i think i am doing something wrong.Please help me to correct my code.Please try to include some sort of explanation, why my code is incorrect. Thanks in advance!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MindTraining
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the digits of first number ");
int a=int.Parse(Console.ReadLine());
Console.WriteLine("Enter the digits of second number");
int b = int.Parse(Console.ReadLine());
Random RandomClass = new Random(DateTime.UtcNow.Second);
int RandomNumber = RandomClass.Next(10^(a-1), 10^a);
Console.WriteLine(RandomNumber);
}
}
}
What i am trying to achieve is , I want user to enter number of digits in number a and number of digits in number b
Then program would generate random number, say user entered 2 for a ,then program have to generate numbers between 0 to 10(Random Number, Every time different)
if user entered 3 for a, then between 10 to 100,
Similar thing for b, and then calculating product.Number should not repeat more than 2 times, during program run time.
Ok, i changed my code to
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MindTraining
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the digits of first number ");
int a=int.Parse(Console.ReadLine());
Console.WriteLine("Enter the digits of second number");
int b = int.Parse(Console.ReadLine());
Random RandomClass = new Random(DateTime.UtcNow.Second);
double num1=Math.Pow(10,a-1);
double num2=Math.Pow(a,1);
int num3 = Convert.ToInt32( num1);
int num4=Convert.ToInt32(num2);
int RandomNumber = RandomClass.Next(num3,num4);
Console.WriteLine(RandomNumber);
}}
// But still not getting result, I throws error,
This one worked!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MindTraining
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the digits of first number ");
int a=int.Parse(Console.ReadLine());
Console.WriteLine("Enter the digits of second number");
int b = int.Parse(Console.ReadLine());
Random RandomClass = new Random();
double num1=Math.Pow(10,(a-1));
double num2=Math.Pow(10,(a));
int num3 = Convert.ToInt32( num1);
int num4=Convert.ToInt32(num2);
int RandomNumber = RandomClass.Next(num3,num4);
Console.WriteLine(RandomNumber);
}
}
}
^ is not a raise to the power operator in c#.
Use Math.Pow for this.
The ^ operator in C# means "exclusive or" (XOR), not exponentiation. Read about it here: http://www.dotnetperls.com/xor . Try Math.Pow instead.
is there any reason you want to use a seed value that is so limited? Why not use
Random RandomClass = new Random();
which takes a default time based seed value for your object?
Also, use Math.pow(base,exp) to calculate the range for your Random.next() calls as:
int RandomNumber = RandomClass.Next((int)Math.Pow(10,(a-1)), (int)Math.Pow(10,a));
In your code, the error occurs because,
double num2=Math.Pow(a,1);
returns a itself. So, your maxvalue in the Random.next() is lower than your minvalue, which is logically incorrect. This is the error, I got from running your code, that is apart from the fact that you are missing a closing brace at the end.
Also, you must realise that there is no such thing as a perfectly random number generator. All these are pseudo-random generators. They follow the normal distribution of numbers on the number line. So, to say that a number will not be generated more than twice in one execution is not feasible unless you store all the numbers generated and keep checking against them. This should be a last resort, only is case of dire requirements.
While generating a TRULY random number you cannot suppose that the number is different all the time,hope you got the point. So you need to additionally make sure that the number is different each time.

Categories