IndexOutOfRange exception when using int variable as array selector - c#

I'm trying to create a very basic login system in C# using arrays for username and password comparing.
I'm using a for() loop to compare the username and password the user provides with the usernames and passwords that are in my arrays. Here's my loop code:
string user = null, usrpassword = null;
string[] usernames = {"admin", "guest"};
string[] userpasswords = {"adminpw", "guestpw"};
Console.Write("Username: "); //Username
user = Console.ReadLine();
Console.Write("Password: "); //Password
usrpassword = Console.ReadLine();
Console.WriteLine("Processing...");
for (int i = 0; i <= usernames.Length; i++)
{
if (user == usernames[i] && usrpassword == userpasswords[i])
{
loginloop = false;
Console.WriteLine("Login Successful.");
}
else if (i > usernames.Length)
{
//incorrect username
Console.WriteLine("Incorrect username or password!");
}
} //for-loop-end
I don't get any syntax errors when I build, but when it reaches the for loop it crashes and gives me a IndexOutOfRange exception.

Array indexes start at 0 and go up to Length - 1, so you only want to continue the loop while the iterator is less than Length.
Change the <= to a <:
for (int i = 0; i < usernames.Length; i++)
{
...
}

You just have an "off by one" style error in your for loops conditions;
for (int i = 0; i <= usernames.Length; i++)
should instead be
for (int i = 0; i < usernames.Length; i++)
The array is "zero indexed" where as the Length property is the length counting from one to n. The final index is actually the value one less than Length or 0 in the case of an empty array.

Related

Try/catch in for-loop

I'm new to programming and trying to solve a problem. I've got an array I want to fill with input from a user but I want to make sure it's only integers between 1-25 and no string input. How do I do this?
The code I've gotten this far is this:
for (int i = 0; i < lottery.Length; i++)
{
Console.Write(i + ": ");
try
{
input = int.Parse(Console.ReadLine());
lottery[i] = input;
}
catch
{
Console.WriteLine("Only integers!");
i--;
}
}
This codes makes sure the only input to the array is integers but how do I get the user to only write numbers between 1-25? I've tried diffrent if-statements and other loops 3 hours but can't solve it. Please help.
You should not use exceptions to drive through your code. Exceptions are costly things in terms of performances and if there is a way to avoid them you should always use that way.
In your case you should use int32.TryParse instead of Parse. This TryParse doesn't raise an exception if the input is not a valid integer number but returns false or true while the parsed number (if it is an integer) is returned in the out parameter passed to the method.
This allows to write a lot simpler code with a while loop to continue input in case of errors.
for (int i = 0; i < lottery.Length; i++)
{
Console.Write(i + ": ");
// Start the loop with an invalid input
int input = 0;
while(input == 0)
{
if(int32.TryParse(Console.ReadLine(), out input);
{
// Got a valid integer, add out acceptance logic here
if(input > 0 && input <= 25)
lottery[i] = input;
else
{
Console.WriteLine("Type a number between 1 and 25");
// Not a valid range. Force the loop to continue
input = 0;
}
}
else
Console.WriteLine("Write only integers between 1-25");
}
}
int[] lottery = new int[5];
for (int i = 0; i < lottery.Length; i++)
{
Console.WriteLine(i + ": ");
int input;
while(true)
{
string inp = Console.ReadLine();
if(Int32.TryParse(inp, out input) == true)
{
if (0 < input & input <= 25)
{
break;
}
else
{
Console.WriteLine("Only numbers 1-25");
}
}
else
{
Console.WriteLine("Only Integers");
}
}
lottery[i] = input;
}

Printing even numbers with commas except the last in C# not working

I have been trying to fix this issue for some days now but can't find the error. It seems as simple as an if statement for the code to print commas for all but the last number. It worked for me putting random numbers but when i put the specific numbers (24,7,35,2,27,7,89)it prints the comma at the end.
Print even numbers with commas
This is my code, but i tried multiple other ways.
using System.Collections.Generic;
using System.Text;
using System.Transactions;
namespace ArrayExercises
{
class TaskFour
{
public static void FindEvenNumbers()
{
int[] input = new int[7];
int count = 1;
string comma = ",";
Console.WriteLine("[== Please Enter 7 numbers ==]");
Console.WriteLine();
for (int i = 0; i < input.Length; i++)
{
Console.WriteLine($"Enter number {count}:");
input[i] = int.Parse(Console.ReadLine());
count++;
}
Console.WriteLine("The even numbers in this array are: ");
for (int i = 0; i < input.Length; i++)
{
if (input[i] % 2 == 0)
{
if (i < input.Length)
{
Console.Write(input[i] + comma);
}
else
{
Console.Write(input[i]);
}
}
}
}
}
}
Thanks in advance :)
You can use below code without introducing any extra space using for loop.
for (int i = 0; i < input.Length; i++)
{
if (input[i] % 2 == 0)
{
if (i != 0) Console.Write(comma);
Console.Write(input[i]);
}
}
Or use the inbuilt string.Join function.
Console.WriteLine(string.Join(',', input.Where(i => i % 2 == 0)));
This answer assumes that the above is homework/tutorial, there are more efficient means that what I am posting here
The problem is this segment:
if (i < input.Length)
{
Console.Write(input[i] + comma);
}
The problem is that you are always outputting a comma, regardless of what is to follow. I think that the easiest approach would be to add the comma before hand, meaning, while you are going through the second loop, if you have already printed a number before, you pre-pend a comma and print the number you have, if you did not print any numbers before (that is, you are about to print the first number) then you do not prepend the comma.
i will always be less than the length the input due to the loop's condition.
Instead of implementing this yourself, you could let string.join do the heavy lifting for you:
string result = string.Join(comma, input.Where(i => i % 2 == 0));
Console.WriteLine(result);
Your else condition will never execute. If you are rookie in C# then I would suggest get all even numbers first and store it in the list. Iterate over again to print with comma and just skip the last comma.
//Your existing source code
List<int> evenNumber = new List<int>();
for (int i = 0; i < input.Length; i++)
{
if (input[i] % 2 == 0)
{
evenNumber.Add(input[i]);
}
}
for(int i = 0; i < evenNumber.Length; i++)
{
//Print just number if it is last, otherwise print number with comma
if(i == evenNumber.Length - 1)
Console.Write(evenNumber[i]);
else
Console.Write(evenNumber[i]+comma);
}
If you know string.Join() then use linq to get list of even numbers and print list of even numbers with ',' as a delimiter
var evenNumbers = input.Where(x => x % 2 ==0); //Filter all even numbers
Console.WriteLine(string.Join(",", evenNumbers); //Print using string.Join
Yet another version:
string result = "";
for (int i = 0; i < input.Length; i++)
{
if (input[i] % 2 == 0)
{
result += $",{input[i]}";
}
}
Console.WriteLine( result.Length > 0 ? result.Substring(1).ToString() : "");

C# Array - identify the input if it is repeating or not

I want to create an algorithm that would identify if the user input is repeating or not. If it is repeating it will prompt the user a message if its not repeating it will continue the process.
public static class Program
{
public static void Main()
{
Console.WriteLine("input array of numbers: );
int[] array = new int[4];
for(int i=0; i<3; i++)
{
array[i] = int.Parse(Console.ReadLine());
if(array[i] == array[0])
{
Console.WriteLine("repeating inputs")
}
}
Console.WriteLine("Highest number is:" + array.MaxLenght);
Console.ReadLine();
}
}
Explanation: The user will be prompted by message "inter array of numbers:" then the user will now input the numbers. If the user inputs the same number or if the number was already inputted, the user will be prompted by a message something like "repeating inputs! Input another number". After the user input another number unique to the previously interred the program will continue and print out the largest number base on the inputs.
i'm not sure if I understood you correctly but this is what i can extrapolated from your post :
you want to get input from the user and check if it's repeating or not and then print the highest number (based on your Console.WriteLine("Highest number is:" + array.MaxLenght); )
this is how i'd approach it
Console.WriteLine("input array of numbers: ");
List<int> uniqueInts = new List<int>();
int[] array = new int[4];
for (int i = 0; i < 3; i++)
{
array[i] = int.Parse(Console.ReadLine());
if (!uniqueInts.Contains(array[i]))
uniqueInts.Add(array[i]);
}
//getting the max number
//assuming the first number is the max
int max = uniqueInts[0];
for (int i = 1; i < uniqueInts.Count; i++)
{
if (max < uniqueInts[i])
max = uniqueInts[i];
}
Console.WriteLine("The highest number is : " + max);
There are a lot of assumptions that I'm making with this answer. I'm assuming you're struggling to get the value of the item prior to the current iteration considering you have if(array[i] == array[0]).
If that's the case, then simply change array[0] to array[i-1].
Wait! Before you do that, you need to add a check to make sure you aren't on the first iteration. If you don't, you'll get an exception thrown on the first iteration, because you'll be trying to grab array[-1], which isn't valid.
for(int i=0; i<3; i++)
{
array[i] = int.Parse(Console.ReadLine());
if(i > 0)
{
if (array[i] == array[i-1])
Console.WriteLine("repeating inputs")
}
}
Make these few changes, and I think you'll get what you're after.

C# cant understand count

I am trying to count words in this program but i don't understand why the program is counting for 1 number less than it must be.
For example:
sun is hot
program will show me that there is only 2 words.
Console.WriteLine("enter your text here");
string text = Convert.ToString(Console.ReadLine());
int count = 0;
text = text.Trim();
for (int i = 0; i < text.Length - 1; i++)
{
if (text[i] == 32)
{
if (text[i + 1] != 32)
{
count++;
}
}
}
Console.WriteLine(count);
Regular expression works the best for this.
var str = "this,is:my test string!with(difffent?.seperators";
int count = Regex.Matches(str, #"[\w]+").Count;
the result is 8.
Counts all words, does not include spaces or any special characters, regardless if they repeat or not.

Sorting array numbers in c#

I have an assingment and I'm a bit lost. In an array of 10 (or less) numbers which the user enters (I have this part done), I need to find the second smallest number. My friend sent me this code, but I'm having a hard time understanding it and writing it in c#:
Solved it!!! :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int vnesena;
int? min1 = null;
int? min2 = null;
for(int i=1; i<11; i=i+1)
{
Console.WriteLine("Vpiši " + i +"." + " število: ");
vnesena = Convert.ToInt32(Console.ReadLine());
if (vnesena == 0)
{
break;
}
if (min1 == null || vnesena < min1)
{
min2 = min1;
min1 = vnesena;
}
else if (vnesena != min1 && (min2==null || vnesena<min2))
{
min2 = vnesena;
}
}
if (min1 == null || min2 == null)
{
Console.WriteLine("Opozorilo o napaki");
}
else
{
Console.WriteLine("Izhod: " + min2);
}
Console.ReadKey();
}
}
}
That code is too complicated, so try something like this.
int[] numbers = new int[10];
for (int i = 0; i < 10; i++)
{
numbers[i] = int.Parse(Console.ReadLine());
}
Array.Sort(numbers);
Console.WriteLine("Second smallest number: " + numbers[1]);
If the code isn't too obvious, let me explain:
Declare an array of 10 integers
Loop 10 ten times and each time, ask for user input & place input as an integer to the array
Sort the array so each number is in the number order (smallest first, biggest last).
The first integer is smallest (input at index 0, so numbers[0]) and the second smallest is obviously numbers[1].
Of course, for this piece of code to work, you have to use this code in console program.
As you didn't mention if you are allowed to use built in sorting functions etc, I assume that Array.Sort() is valid.
EDIT: You updated your topic so I'll change my code to match criterias.
int[] numbers = new int[10];
bool tooShortInput = false;
for (int i = 0; i < 10; i++)
{
int input = int.Parse(Console.ReadLine());
if (input != 0)
{
numbers[i] = input;
}
else
{
if (i == 2)
{
Console.WriteLine("You only entered two numbers!");
tooShortInput = true;
break;
}
else
{
for (int j = 0; j < 10; j++)
{
if (numbers[j] == 0)
{
numbers[j] = 2147483647;
}
}
break;
}
}
}
// Sort the array
int temp = 0;
for (int write = 0; write < numbers.Length; write++) {
for (int sort = 0; sort < numbers.Length - 1; sort++) {
if (numbers[sort] > numbers[sort + 1]) {
temp = numbers[sort + 1];
numbers[sort + 1] = numbers[sort];
numbers[sort] = temp;
}
}
}
if (!tooShortInput)
{
Console.WriteLine("Second smallest number: " + numbers[1]);
}
If you don't understand the updated code, let me know, I will explain.
NOTE: This is fastly coded and tested with android phone so obviously this code isn't 5 star quality, not even close, but it qualifies :-).
Regards, TuukkaX.
To paraphrase the code given:
Set 2 variables to nothing. (This is so that there can be checks done later. int? could be used if you want to use null for one idea here.
Start loop through values.
Get next value.
If the minimum isn't set or the new value is lower than the minimum, replace the second lowest with the former lowest and lowest with the new value that was entered.
Otherwise, check if the new value isn't the same as the minimum and if the minimum isn't set or the entered value is lower than the second lowest then replace the second lowest with this new value.
Once the loop is done, if either minimum value isn't filled in then output there isn't such a value otherwise output the second lowest value.
Imagine if you had to do this manually. You'd likely keep track of the lowest value and second lowest value as you went through the array and the program is merely automating this process. What is the problem?
This is a rough translation of what your friend gave you that isn't that hard to translate to my mind.
int enteredValue;
int? smallest = null, secondSmallest = null;
for (int i = 0; i < 10; i = i + 1)
{
Console.WriteLine("Vpiši " + i+1 + " število: ");
enteredValue = Convert.ToInt32(Console.ReadLine());
if (smallest==null || enteredValue<smallest) {
secondSmallest=smallest;
smallest = enteredValue;
} else if (enteredValue!=smallest && enteredValue<secondSmallest) {
secondSmallest= enteredValue;
}
}
Why use a loop and not take advantage of the Array.Sort method?
int[] numbers = new int[4] { 4, 2, 6, 8 };
Array.Sort(numbers);
int secondSmallestNumber = numbers[1];

Categories

Resources