for loop not executing/running correctly - c#

Here's the code can anyone help?
using System;
namespace Mathhero
{
class MainClass
{
public static void Main(string[] args)
{
int i;
for (i = 0; i <= 10; i++)
{
Random numgen = new Random();
int num1 = numgen.Next(1, 11);
int num2 = numgen.Next(1, 11);
Console.WriteLine("What is " + num1 + " * " + num2 + " equal to ???");
int Answer = Convert.ToInt32(Console.ReadLine());
if (Answer == num1 * num2)
{
int ran = numgen.Next(1, 4);
switch (ran)
{
case 1:
Console.WriteLine("Good work!!");
break;
case 2:
Console.WriteLine("Nice!!!");
break;
default:
Console.WriteLine("Excellent!!");
break;
}
Console.WriteLine();
}
else
{
int ran = numgen.Next(1, 4);
switch (ran)
{
case 1:
Console.WriteLine("Wrong!!");
break;
case 2:
Console.WriteLine("Try hard!!!");
break;
default:
Console.WriteLine("DO homework!!");
break;
}
Console.WriteLine();
}
i=i+ 1;
}
Console.WriteLine("Test Ended!!!");
}
}
}
The for loop is exiting after 6 questions while it should after 10.

You are increasing your index within the for loop and thus shortening it's run.
else
{
int ran = numgen.Next(1, 4);
switch (ran)
{
case 1:
Console.WriteLine("Wrong!!");
break;
case 2:
Console.WriteLine("Try hard!!!");
break;
default:
Console.WriteLine("DO homework!!");
break;
}
Console.WriteLine();
}
i=i+ 1; //// <------- HERE
}
Your for loop already takes care of incrementing the index by itself.

Your for loop "header" increments i in the normal way:
for (i = 0; i <= 10; i++)
However, within the loop you also increment i, for no apparent reason:
i=i+ 1;
So you're incrementing i twice for each iteration of the loop. That makes it reach its end point earlier.
To execute 10 times, you should have:
for (i = 0; i < 10; i++)
(note the use of < rather than <=) and remove the i = i + 1; statement entirely.
I'd also recommend the general principle of declaring each variable in as small a scope as you can - in this case, in the for loop:
for (int i = 0; i < 10; i++)
That's more idiomatic and "tidy" IMO than declaring it before the loop.

the loop will run for 11 times as you are initializing i=0 and i<=10 so should check this...
Second i don't understand why are you doing i+1 at the end because loop is already incrementing so you should check this also..

Related

Local variables - switch case

I am studying programming and I am very beginner (started 2 months ago).
I am doing a c# exercise for maths calculation. Our professor used a if ... else (embricated) loops to do the exercise. I wanted to use a switch case but I am struggling with the local variables.
I understand the issue: case 2 and 3 does not "know" the variables totalNumber and nbrSubAssy is as they come from case 1 and case 2, then they are detected as not assigned.
If I still want to use a switch case, what could I do to solve it?
using System;
namespace Denombrements
{
class Program
{
static long IntMultiplication(int startValue, int endValue)
{
long multiplication = 1;
for (int k = startValue; k <= endValue; k++)
multiplication *= k;
return multiplication;
}
static int UserSelection(String message)
{
int number = 0;
Console.Write(message);
try
{
number = int.Parse(Console.ReadLine());
Console.WriteLine();
}
catch
{
Console.WriteLine();
Console.WriteLine("Wrong input, enter an integer");
}
return number;
}
static void Main(string[] args)
{
char choice = '1';
while (choice != '0')
{
Console.WriteLine("Permutation ...................... 1");
Console.WriteLine("Arrangement ...................... 2");
Console.WriteLine("Combination ...................... 3");
Console.WriteLine("Quit ............................. 0");
Console.Write("Choice : ");
choice = Console.ReadKey().KeyChar;
Console.WriteLine();
switch(choice)
{
case '0':
Environment.Exit(0);
break;
case '1':
int totalNumber = UserSelection("Total number of elements to be taken into account");
long permutation = IntMultiplication(1, totalNumber);
Console.WriteLine(totalNumber + "! = " + permutation);
break;
case '2':
int nbrSubAssy = UserSelection("Total number of elements in the subassy to be taken into account");
long arrangement = IntMultiplication(totalNumber - nbrSubAssy + 1, totalNumber);
Console.WriteLine("A(" + totalNumber + "/" + nbrSubAssy + ") = " + arrangement);
break;
case '3':
long combination = arrangement / IntMultiplication(1, nbrSubAssy);
Console.WriteLine("C(" + totalNumber + "/" + nbrSubAssy + ") = " + combination);
break;
default:
Console.WriteLine("Wrong input");
break;
}
}
Console.ReadLine();
}
}
}
Declare your variable before While loop and it will keep the value of it for all the life of LOOP and you could access the old values
char choice = '1';
int nbrSubAssy = 0;
int totalNumber = 0;
long arrangement = 0;
while (choice != '0')
{
// code ...
switch (choice)
{
case '0':
Environment.Exit(0);
break;
case '1':
totalNumber = UserSelection("Total number of elements to be taken into account");
long permutation = IntMultiplication(1, totalNumber);
Console.WriteLine(totalNumber + "! = " + permutation);
break;
case '2':
nbrSubAssy = UserSelection("Total number of elements in the subassy to be taken into account");
arrangement = IntMultiplication(totalNumber - nbrSubAssy + 1, totalNumber);
Console.WriteLine("A(" + totalNumber + "/" + nbrSubAssy + ") = " + arrangement);
break;
case '3':
long combination = arrangement / IntMultiplication(1, nbrSubAssy);
Console.WriteLine("C(" + totalNumber + "/" + nbrSubAssy + ") = " + combination);
break;
default:
Console.WriteLine("Wrong input");
break;
}
}
or in my opinion the better solution you could ask for the value in every case you need them

Control Cannot Fall Through From One Case Label To Another Even With Break

This is some part of the code.
I am getting the error "Control cannot fall through from one case label to another in case 3".
In spite of using the break statement, it is not getting detected. What is the right way to do it?
Update: Error is in case 3. Don't bother to waste your time on other cases.
switch (output)
{
case 1:
int num, reverse = 0;
Console.WriteLine("Enter a Number : ");
num = int.Parse(Console.ReadLine());
while (num != 0)
{
reverse = reverse * 10;
reverse = reverse + num % 10;
num = num / 10;
}
Console.WriteLine("Reverse of Number is : "+reverse);
Console.ReadLine();
break;
case 2:
int number, sum = 0, r,square;
Console.WriteLine("Enter a Number : ");
number = int.Parse(Console.ReadLine());
while (number != 0)
{
r = number % 10;
number = number / 10;
square = r * r;
sum = sum + square;
}
Console.WriteLine("Sum of square of Digits of the Number : "+sum);
Console.ReadLine();
break;
case 3:
Console.WriteLine("Enter 1 for AND 2 for OR and 3 for XOR Operation");
int answer = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Your 2 inputs are?");
int inp1= Convert.ToInt32(Console.ReadLine());
int inp2= Convert.ToInt32(Console.ReadLine());
switch (answer)
{
case 1:
int input3 = inp1 * inp2;
System.Console.WriteLine("Output is" + input3);
Console.ReadLine();
break;
case 2:
int input4 = inp1 + inp2;
System.Console.WriteLine("Output is" + input4);
Console.ReadLine();
break;
case 3:
if (inp1 == inp2)
{
System.Console.WriteLine("OUTPUT IS 0");
Console.ReadLine();
}
else
{
System.Console.WriteLine("Output is 1");
Console.ReadLine();
}
break;
Your problem is that you only break out of the inner case and not the outer, so you're getting a fall through issue.
case 3 ...
case 3:
if (inp1 == inp2)
{
System.Console.WriteLine("OUTPUT IS 0");
Console.ReadLine();
}
else
{
System.Console.WriteLine("Output is 1");
Console.ReadLine();
}
break;
break; //break the outer case3
Add a goto case X in place of the break for where you want the fall though to occur.
... never mind. you need an expression block on the first case 3.
case 3
{
/// your other switch here
break;
}
By not using scoping blocks you overlooked the outer case statement. It needs break as well as the inner statement.

Static random member still outputting the same number each time

I have a static random member that when I use rand.next(1,2) I always get 1. I don't understand why.
static Random rand = new Random();
private static void Attack(Player player, Monster monster)
{
var pDamage = Convert.ToInt32(Math.Floor(player.Weapon.Attack * monster.Armor.DamageRedux));
Console.WriteLine("You strike the {0} for {1} damage.", monster.MonsterName, pDamage);
monster.Health -= pDamage;
for (int i = 0; i < 10; i++)
{
var hitRoll = rand.Next(1, 2);
Console.Write("{0}", hitRoll);
}
switch (1)
{
case 1:
var mDamage = Convert.ToInt32(Math.Floor(monster.Weapon.Attack * player.Armor.DamageRedux));
Console.WriteLine("The {0} swing back and hits you for {1} damage.", monster.MonsterName, mDamage);
player.Health -= mDamage;
break;
case 2:
Console.WriteLine("The {0} swings wildly at you and misses.", monster.MonsterName);
break;
}
}
The max value is exclusive when the min value is inclusive. Visually:
minValue ●—— value ——○ maxValue
or as an expression
minValue <= value && value < maxValue
Here is the documentation for Next: https://msdn.microsoft.com/en-us/library/2dx6wyd4(v=vs.110).aspx
You should change the values sent to the Next() method:
var hitRoll = rand.Next(1, 3); // Generates a value between 1 and 2

How can I get this code to loop correctly?

int a = 0;
int b = 0;
for (int c = 0; c < 2; c++)
{
Console.WriteLine("Give me a number");
int h = Convert.ToInt16(Console.ReadLine());
switch (c)
{
case 0:
a = h;
while (a <100 || a>250)
{
Console.WriteLine("That number is too large");
break;
}
break;
case 1:
b = h;
while (a < 100 || a > 250)
{
Console.WriteLine("That number is too large");
break;
}
break;
}
}
Console.WriteLine("{0}",a+b);
Console.ReadKey();
When I input numbers greater than 250 or less than 100 it does give me the message ("That number is too large") but the problem is that it still executes the addition at the end of the code. I am trying to make it so that if those numbers fall outside of that range, it asks me again for the numbers. Any tips on how I can do this?
Subroutines are wonderful things, and useful in many situations.
int GetNumberBetween( int minValue, int maxValue )
{
int h;
for (;;)
{
Console.WriteLine("Give me a number");
h = Convert.ToInt32(Console.ReadLine());
if ( h >= minValue && h <= maxValue )
break;
Console.WriteLine("I don't like that number, try again");
}
return( h );
}
void DisplaySum( void )
{
int a = GetNumberBetween( 100, 250 );
int b = GetNumberBetween( 100, 250 );
Console.WriteLine("{0}",a+b);
Console.ReadKey();
}
You need a better control on your external loop. Instead of a for use a while and increment the variable C only when you have a good number.
int a = 0;
int b = 0;
int c = 0;
while (c < 2)
{
Console.WriteLine("Give me a number");
int h;
if(!Int32.TryParse(Console.ReadLine(), out h)
{
Console.WriteLine("Not a valid number");
continue;
}
switch (c)
{
case 0:
a = h;
if(a <100 || a>250)
Console.WriteLine("That number is too large");
else
c = 1;
break;
case 1:
b = h;
if(b < 100 || b > 250)
Console.WriteLine("That number is too large");
else
c = 2;
break;
}
}
Console.WriteLine("{0}",a+b);
Console.ReadKey();
By the way, I suggest to use Int32.TryParse instead of Convert.ToInt32 (What happen in your code if the user types something that cannot be converted to a number?)
I have also fixed a typo in your second test. You should use the variable b instead of a
You're over thinking the solution. If you are just trying to sum two numbers, then simply do that. Think of it logically. You can add the error messages as needed.
Get the number for a
Get the number for b
Sum the numbers
Note: If you need to sum more than two numbers then this solution won't work
//...
int a = 0;
//Capture a value for a, and range check it
while (a < 10 || a > 50)
{
Console.WriteLine("Give me a number for (a)");
a = Convert.ToInt32(Console.ReadLine());
}
int b = 0;
//Capture a value for b, and range check it
while (b < 10 || b > 50)
{
Console.WriteLine("Give me a number for (b)");
b = Convert.ToInt32(Console.ReadLine());
}
Console.WriteLine("{0}", a + b);
Console.ReadKey();
//...
EDIT:
int a = 0;
//Get a value for a
while (true)
{
Console.WriteLine("Give me a number for (a)");
a = Convert.ToInt32(Console.ReadLine());
//Range check and exit if valid
if (a >= 10 && a <= 50)
break;
Console.WriteLine("That number is too large");
}
int b = 0;
//Get a value for b
while (true)
{
Console.WriteLine("Give me a number for (b)");
b = Convert.ToInt32(Console.ReadLine());
//Range check and exit if valid
if (b >= 10 && b <= 50)
break;
Console.WriteLine("That number is too large");
}
Console.WriteLine("{0}", a + b);
Console.ReadKey();

Index out of Range exception in C# when iterating through an array

I have this code I'm using to create a program that takes a a range and outputs to the Console the prime numbers. I have one problem, I'm trying to iterate through the array I built so the loop should only write to the console the values that are prime using my method's return value. The problem I'm having is that I have the second condition set to numArray.Length but it seems to give me the Index out of Range Exception. I just want the loop to iterate through all values in the numArray and stop when it's done figuring out whether the last value is prime or not.
public struct Prime
{
public int x;
// constructor for Prime
public Prime(int x1)
{
x = x1;
}
public int IsPrime(int number)
{
int i;
for (i = 2; i * i <= number; i++)
{
if (number % i == 0) return 0;
}
return 1;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter an Integer");
int num1 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter a Second Integer of Greater Value");
// int num2 = 0;
int num2 = Convert.ToInt32(Console.ReadLine());
/* if (num2temp > num1)
{
num2temp = num2;
}
else
{
Console.WriteLine("You Did Not Enter An Integer Greater Than the First Integer, Please Enter Your Integers Again.");
Environment.Exit(0);
}
*/ int index = 1;
int[] numArray = new int[num2];
for (int i = num1; i <= num2; i++)
{
numArray[index] = i;
Console.WriteLine(" index: {0} assignment: {1}", index, i);
index++;
Console.WriteLine("index: {0}",index);
}
Console.WriteLine("value: {0}", numArray[40]);
/* Prime myprime = new Prime();
if (myprime.IsPrime(numArray[12]) == 1)
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("False");
} */
Prime myprime = new Prime();
int value = 0;
for (int y = 1; y <= num2; y++)
{
if (myprime.IsPrime(numArray[y]) == 1)
{
value = numArray[y];
Console.Write("{0} \t", value);
}
}
You're currently trying to iterate up to and including the size of the array. Arrays are 0-indexed in C#. So this:
int[] numArray = new int[num2];
for (int i = num1; i <= num2; i++)
should be:
for (int i = num1; i < num2; i++)
And note that to get at the first element array, num1 would have to be 0, not 1.
Likewise, your initial assignment of index as 1 should be 0 instead. Basically you need to go through all your code (it's confusing at the moment with lots of bits commented out) and check everywhere that you're assuming arrays are 1-based, and instead change your code as they're 0-based.
(In some cases you may just want to make the array one bigger, of course. If you want an array which logically contains the values 1 to x inclusive, you can either create an array of size x and subtract one from each index all the time, or create an array of size x + 1.)
Your index starts from 1 but should start from 0:
int index = 0; //CHANGE HERE
int[] numArray = new int[num2];
for (int i = num1; i <= num2; i++)
{
numArray[index] = i;
Console.WriteLine(" index: {0} assignment: {1}", index, i);
index++;
Console.WriteLine("index: {0}",index);
}
and then here y should also be 0 and check should if it is less than num2:
for (int y = 0; y < num2; y++)
{
if (myprime.IsPrime(numArray[y]) == 1)
{
value = numArray[y];
Console.Write("{0} \t", value);
}
}
because array indexing in C# start from 0.

Categories

Resources