This program asks the user for an array size then asks the user to enter in the array values. The problem I am having is that the for loop to read in the array values doesn't work properly. No matter what is the value for nit will sitll ask for a lot more inputs.
int n;
Console.WriteLine("Enter how many values you are entering in");
n = Convert.ToInt32(Console.Read());
int[] arr = new int[n];
Console.WriteLine("Enter your values in");
for (int i = 0; i < n; i++)
{
arr[i] = Convert.ToInt32(Console.Read());
}
Quick and easy fix:
Use int.Parse(Console.ReadLine()) in place of your Convert.ToInt32(Console.Read())
Explanation:
You were getting the ASCII value the way you were doing it. For example, if you would type in the number 2 your n variable would have actually been set to 50.
for (int i = 0; i < n; i++)
{
string value = Console.ReadLine();
int result;
if (int.TryParse(value, out result)) arr[i] = result;
else
{
Console.WriteLine("Invalid value try again.");
i--;
}
}
Use Console.ReadLine() instead of Console.Read().
As documented here, Console.Read() returns only a single character. You probably want to read in the entire line and parse it for the integer value.
This code should do what you want:
int n;
Console.WriteLine("Enter how many values you are entering in");
//n = Convert.ToInt32(Console.Read());
n = Int32.Parse(Console.ReadLine());
int[] arr = new int[n];
Console.WriteLine("Enter your values in");
for (int i = 0; i < n; i++)
{
arr[i] = Int32.Parse(Console.ReadLine());
}
This works in the input case of n = 10 as well.
here is a version with some more robust error checking.
Note: (entering this directly without running, so I apologise if there are minor syntax errors)
int count;
bool attemptedSetCount = false;
do
{
if (attemptedSetCount)
{
Console.WriteLine("Please enter a valid integer");
}
Console.WriteLine("Enter how many values you are entering in");
string countString = Console.ReadLine();
attemptedSetCount = true;
}
while (!Int32.TryParse(countString, out count));
int[] arr = new int[n];
Console.WriteLine("Enter your values in");
for (int i = 0; i < count; i++)
{
string valString = (Console.ReadLine());
int val;
if(!Int32.TryParse(valString, out val))
{
Console.WriteLine("Please enter a valid integer");
i--;
}
else
{
arr[i] = val;
}
}
The Console.Read function reads the next single character of input and returns it as as int value. The code then passes it to the Convert.ToInt32 API which will essentially return the exact value that was passed in. This means that numbers like 1 which have the character value 49 will be processed as 49. This is why your code is reading in so many values
To properly read a number from the Console use the ReadLine method which returns a String. This can then be passed to Int32.Parse and converted to an int
Int32.Parse(Console.ReadLine());
Or better yet, just abstract this out to a method
static int ReadInt() {
return Int32.Parse(Console.ReadLine());
}
Use ReadLine() to get the number, then use ReadKey() not Read() or ReadLine() when entering the chararcters
int n;
Console.WriteLine("Enter how many values you are entering in");
n = Convert.ToInt32(Console.ReadLine());
int[] arr = new int[n];
Console.WriteLine("Enter your values in");
for (int i = 0; i < n; i++)
{
char c = Console.ReadKey().KeyChar;
arr[i] = Convert.ToInt32(c.ToString());
}
Have you read the documentation?
The Read method blocks its return while you type input characters;
it terminates when you press the Enter key. Pressing Enter appends a
platform-dependent line termination sequence to your input (for example,
Windows appends a carriage return-linefeed sequence). Subsequent calls to the
Read method retrieve your input one character at a time. After the final
character is retrieved, Read blocks its return again and the cycle repeats.
Note that you will not get a property value of -1 unless you perform one of the
following actions: simultaneously press the Control modifier key and Z console
key (Ctrl+Z), which signals the end-of-file condition; press an equivalent key
that signals the end-of-file condition, such as the F6 function key in Windows;
or redirect the input stream to a source, such as a text file, that has an actual
end-of-file character.
The ReadLine method, or the KeyAvailable property and ReadKey method are
preferable to using the Read method.
If I execute this code:
Console.Write("? ") ;
int input = Console.Read() ;
Console.WriteLine("You entered {0}.", input ) ;
Console.WriteLine( "{0} is the decimal code point for the character whose glyph is '{1}.'" , input , (char)input ) ;
And, if I, at the ? prompt, enter the characters 123 followed by the return key:
? 123<return>
I'll see this output:
You entered 49.
49 is the decimal code point for the character whose glyph is '1'.
[Note that in Windows, you can generate a '1' at the command prompt by holding down the <ALT> key, typing '0049and releasing the` key.]
Assuming that the intent is for the user to specify a number of values to be entered and to then prompt them for that many input values, you want code that looks something like this:
static void Main()
{
int n = ReadIntegerFromConsole( "How many values do you want to enter?" ) ;
int[] values = new int[n] ;
for ( int i = 0 ; i < values.Length ; ++i )
{
string prompt = string.Format( "{0}/{1}?" , i , n ) ;
values[i] = ReadIntegerFromConsole(prompt) ;
}
Console.WriteLine( "You entered: {0}" , string.Join(", ",values) ) ;
return ;
}
static int ReadIntegerFromConsole( string prompt )
{
int value ;
bool isValid ;
do
{
Console.Write( prompt) ;
Console.Write( ' ' );
string text = Console.ReadLine() ;
isValid = int.TryParse(text, out value ) ;
prompt = "That's not an integer. Try again:" ;
} while (!isValid) ;
return value ;
}
Related
I do not understand why this code prints the contents of the array twice.
static void Main(string[] args)
{
Int64 userlength;
Int64 userlengthcounter;
String unencrypted;
char current;
start:
Console.WriteLine("Please enter how many characters the string you want encrypyted to be:");
userlength = Convert.ToInt64(Console.ReadLine());
Console.WriteLine("Please enter the string you want to be encrypted:");
unencrypted = Console.ReadLine();
int[] first = new int[userlength];
int[] second = new int[userlength];
if (userlength != unencrypted.Length)
{
Console.WriteLine("The string you entered was not the same length as the number of characters you specified");
goto start;
}
for (int i = 0; i < userlength; i++)
{
Console.WriteLine(unencrypted[i]);
current = unencrypted[i];
first[i] = current;
}
foreach (char item in first)
{
Console.WriteLine(item.ToString());
}
Console.ReadLine();
}
For example entering abcd would return abcdabcd and i don't understand why. Any help would be appreciated thanks.
It's because you have two loops, first you print each character in unencrypted in the for loop and store the chars in first array.
Then you loop over the array and print the chars again with foreach.
Additional Note: Using goto is almost always a bad idea because it makes your code hard to follow and unreadable. Because you have to manually track where the code jumps.
You can do the same thing with a do-while loop instead.
do {
Console.WriteLine("Please enter how many characters the string you want encrypyted to be:");
userlength = Convert.ToInt64(Console.ReadLine());
Console.WriteLine("Please enter the string you want to be encrypted:");
unencrypted = Console.ReadLine();
int[] first = new int[userlength];
int[] second = new int[userlength];
if (userlength != unencrypted.Length)
{
Console.WriteLine("The string you entered was not the same length as the number of characters you specified");
}
} while(userlength != unencrypted.Length);
you specifically build "first" then you print it in foreach, basically displaying the same content twice:
for (int i = 0; i < userlength; i++)
{
Console.WriteLine(unencrypted[i]);
current = unencrypted[i];
first[i] = current;
}
foreach (char item in first)
{
Console.WriteLine(item.ToString());
}
My apologies if I didn't explain it clear the first time. I have edited my explanation further in bold below.
In the program below user enters a word and then enters a letter which the user would like to replace with any character. For instance, user enter's a word "Hello" and the replacement letter is "l" with "$". So "Hello" will become "He$$o". First, the goal is to find the location of "l" (example - 2,3) and then replace the element in that specific location.
I started by finding the location of "l" and storing it in a findIndex array. Every time I run the program I get "22222" stored in findIndex[] array. At this point, I am not even sure if I am even applying the right logic. Any advice will be appreciated! Please don't use LINQ.
public static void RemoveSpecifiedCharacters()
{
Console.WriteLine("\nWrite a word/sentence: ");
string myString = Console.ReadLine();
Console.Write("Type the character you would like to replace: ");
string myCharacter = Console.ReadLine();
int[] findIndex = new int[myString.Length];
for (int i = 0; i < myString.Length; i++)
{
findIndex[i] = myString.IndexOf(myCharacter, 0);
}
for (int i = 0; i < findIndex.Length; i++)
{
Console.Write(findIndex[i]);
}
}
This is probably what you want :
public static void RemoveSpecifiedCharacters()
{
Console.WriteLine("\nWrite a word/sentence: ");
string myString = Console.ReadLine();
Console.Write("Type the character you would like to replace: ");
string myCharacter = Console.ReadLine();
List<int> findIndex = new List<int>();
int offs = 0;
while (offs < myString.Length)
{
offs = myString.IndexOf(myCharacter, offs);;
if (offs == -1)
break;
findIndex.Add(offs);
offs++;
}
for (int i = 0; i < findIndex.Count; i++)
{
Console.Write(findIndex[i]);
}
}
Set an initial offset to the start of the string, try to find index of required character if not found exit, otherwise store the location & increment the offset so the next loop starts after the found position. Then keep looping.
As you do not know how many characters will be found, then a list is better than an array to store the results. It can always be converted to an array with .ToArray() afterwards.
Below should serve the purpose :
var str = "Hello";
var replaced = str.Replace('l', '$');
Even though it's easier to use String.Replace, I just want to give you an explanation why you are getting [2,2,2,2,2] array.
Firstly, IndexOf method returns index of character's first occurence, starting from 0.
Secondly, you are using method overload IndexOf(myCharacter, 0) which "says" that character search should be done always from the start of the string.
To circumvent the issue, you should use IndexOf(myCharacter, i, 1) instead to set the search to start from i-th character, not the start of string.
I guess a simple solution would be to split the string into a character array and then do the comparison?
For example something like:
Console.WriteLine("\nWrite a word/sentence: ");
char[] myString = Console.ReadLine().ToCharArray();
Console.Write("Type the character you would like to replace: ");
char myCharacter = Console.ReadLine().ToCharArray()[0];
int[] findIndex = new int[myString.Length];
int indexCount = 0;
for (int i = 0; i < myString.Length; i++)
{
if (myString[i] == myCharacter)
findIndex[indexCount++] = i;
}
for (int i = 0; i < indexCount; i++)
{
Console.Write(findIndex[i]);
}
I need some help with a C# program that i am creating. So in this scenario i am inputting duplicate values into the program. For Example, a,b,b,c,c.
The exercise is that if there are any duplicated letters inputted (no numbers) i should get an error stating "Duplicate Value. Please Try Again!" and will not accept the duplicate value, and should show the values as a,b,c,d,e.
class Program
{
static void Main(string[] args)
{
char[] arr = new char[5];
//User input
Console.WriteLine("Please Enter 5 Letters only: ");
for (int i = 0; i < arr.Length; i++)
{
arr[i] = Convert.ToChar(Console.ReadLine());
}
//display
for(int i = 0; i<arr.Length; i++)
{
Console.WriteLine("You have entered the following inputs: ");
Console.WriteLine(arrArray[i]);
}
}
}
Choose right data structure at beginning, use HashSet instead of array since the operations are mainly looking up & inserting.
Using a hashtable (Generic Dictionary) is an efficient way to determine if an entered character has already been encountered.
Also, the Char.IsLetter method in the .NET framework is a great way to check for bad data.
static void Main(string[] args) {
Dictionary<char, bool> charsEntered = new Dictionary<char, bool>();
Console.WriteLine("Please enter 5 characters, each on a separate line.");
while (charsEntered.Count() < 5) {
Console.WriteLine("Enter a character:");
char[] resultChars = Console.ReadLine().ToCharArray();
if(resultChars.Length != 1 || !Char.IsLetter(resultChars[0])) {
Console.WriteLine("Bad Entry. Try again.");
} else {
char charEntered = resultChars[0];
if (charsEntered.ContainsKey(charEntered))
Console.WriteLine("Character already encountered. Try again.");
else
charsEntered[charEntered] = true;
}
}
Console.WriteLine("The following inputs were entered:");
Console.WriteLine(String.Join(", ", charsEntered.Keys));
Console.ReadLine();
}
Use Any linq expression to validate duplicates. char.TryParse will validates input and returns true when succeeded.
public static void Main()
{
char[] arr = new char[5];
//User input
Console.WriteLine("Please Enter 5 Letters only: ");
for (int i = 0; i < arr.Length; i++)
{
char input;
if(char.TryParse(Console.ReadLine(), out input) && !arr.Any(c=>c == input))
{
arr[i] = input;
}
else
{
Console.WriteLine( "Error : Either invalid input or a duplicate entry.");
i--;
}
}
Console.WriteLine("You have entered the following inputs: ");
//display
for(int i = 0; i<arr.Length; i++)
{
Console.WriteLine(arr[i]);
}
}
Working Code
Elaborating on Shelvin's answer of using HashSet
HashSet<char> chars = new HashSet<char>();
//User input
Console.WriteLine("Please Enter 5 Letters only: ");
for (int i = 0; i < 5; )
{
char c = Convert.ToChar(Console.ReadLine());
if(!("abcdefghijklmnopqrstuvwxyz".Contains(c.ToString().ToLower())))
{
Console.WriteLine("Please enter an alphabet");
continue;
}
else if (!chars.Contains(c))
{
chars.Add(c);
i++;
}
else
{
Console.WriteLine("Duplicate value please try again");
continue;
}
}
//display
Console.WriteLine("You have entered the following inputs: ");
foreach(char c in chars)
Console.WriteLine(c.ToString());
Console.Read();
Keep it simple, and although a HashSet is nice semantically, it's not needed for 5 elements (it's actually slower than a List in that case). Worse, it requires a parallel structure to track the characters (assuming you care about order).
Clearly none of these considerations matter for such a small example but it's good to learn them up front and don't always jump to big-O notation when actually measured performance and memory consumption should be your guide for most practical applications.
Instead you can simply do:-
List<char> chars = new List<char>(5);
while (chars.Count < 5)
{
char c = Console.ReadKey().KeyChar;
if (!char.IsLetter(c)) continue;
if (chars.Contains(char)) continue;
chars.Add(char);
}
Plus whatever error messages you want to add.
edit: for those who have answered, I apologize, I should have been more clear, the assignment REQUIRES use of the for loop per my professor.
I'm doing a small assignment for class and am having trouble breaking out of a for loop and prompting the user to enter a valid value. My code is set up thus far as:
const int MINRANGE = 1;
const int MAXRANGE = 20;
int input = 0;
Console.Write("Enter the desired maximum: ");
string strInput = Console.ReadLine();
Console.WriteLine("\n\n\n");
for (int.TryParse(strInput, out input); input >= MINRANGE && input <= MAXRANGE; input--)
{
Console.WriteLine("{0,2} {1,5}", input, Math.Pow(input, 3));
}
The program displays everything I need it to correctly. When the user enters a value out of the range I have specified, I need to give them a short message and then break out of the loop and return to the beginning prompt. I think I need to use something like the following if statement:
if (input >= MAXRANGE || input <= MINRANGE)
{
Console.WriteLine("That is not a valid value, please try again.");
}
Perhaps with a break; following it? But I'm not sure how to use it inside of the for loop. I've tried placing it outside, but that doesn't get me back to the user prompt, but neither does placing it inside the loop, so I'm obviously doing something wrong.
You can use a while loop
int input;
while(!int.TryParse(Console.ReadLine(), out input) || input >= MAXRANGE)
{
Console.WriteLine("Not valid!");
}
Note that this may get the user "stuck" and a helpful message as to why it isn't valid would be nice
If for some bizarre reason you must use a for loop you can use the following but it is horrible code that I would never condone
int input;
for(;;)
{
if(int.TryParse(Console.ReadLine(), out input) && input < MAXRANGE)
break;
}
Its better to do the validation before entering the loop. Try this out.....
const int MINRANGE = 1;
const int MAXRANGE = 20;
int input = 0;
Console.Write("Enter the desired maximum: ");
string strInput = Console.ReadLine();
Console.WriteLine("\n\n\n");
if (input > MAXRANGE || input < MINRANGE)
{
Console.WriteLine("That is not a valid value, please try again.");
}
else
{
for (int.TryParse(strInput, out input); input >= MINRANGE && input <=
MAXRANGE; input--)
{
Console.WriteLine("{0,2} {1,3}", input, Math.Pow(input, 3));
}
}
I would rewrite your code as follows. Creating a method for asking the input:
const int MINRANGE = 1;
const int MAXRANGE = 20;
int input = 0;
string strInput = AskInput();
while (!int.TryParse(strInput, out input)) /*while the number is invalid*/
{
Console.WriteLine("Your input is invalid. Try again.");
strInput = AskInput();
}
while (input >= MINRANGE && input <= MAXRANGE)
{
Console.WriteLine("{0,2} {1,3}", input, Math.Pow(input, 3));
input--;
}
Where AskInput is:
private static string AskInput()
{
Console.Write("Enter the desired maximum: ");
string strInput = Console.ReadLine();
Console.WriteLine("\n\n\n");
return strInput;
}
for ([(fist) Initialization];
[(second)Condition];
[(third or exit the loop) Progression])
{
[(fourth) Loop's body -if we reached third than we got here ]
}
The for loop is constructed of three parts:
The initialization part which happens only once when the loop starts.
The condition evaluation part which happens for every iteration.
The indexer progression part which also happens for every loop.
The order is as follows:
Start Loop => init => CheckCondition => if OK Progress the indexer and execute loop's body, else the loop is done.
The initialization part happens just once, if you want it to happen foreach interation it should be inside the loop or in the conditional section of the loop instead.
Best practice would be to use a while loop when the number of iterations is unknown ahead, like in this case, when it's determined by user's input.
I am new to C# and was doing this program as an exercise. I have managed to get my program to print the reversed number of the input given by the user, but when I move onto checking whether it is a palindrome or not, it does not calculate the answer correctly. It always prints 'not a palindrome'.
After some error checking, I realized that the reason why it was doing this is because the last number that gets stored in newnum is just the last digit after being reversed and not the entire number. How can I rectify this??
My Code
int i, remainder = 0, newnum = 0;
Console.WriteLine("Enter a Number: ");
int uinput = Convert.ToInt32((Console.ReadLine()));
for (i = uinput; i > 0; i = (i / 10))
{
remainder = i % 10;
Console.Write(remainder);
newnum = remainder;
}
if (newnum == uinput)
{
Console.WriteLine("The Number {0} is a palindrome", uinput);
}
else
{
Console.WriteLine("Number is not a palidrome");
}
Console.WriteLine(uinput);
Console.WriteLine(newnum);
Console.ReadKey();
}
I also looked online at another code example, but the thing I don't understand in that is why num is being converted to boolean type in the while loop? Is that just to keep the loop running?
The Code reffered to above
int num, rem, sum = 0, temp;
//clrscr();
Console.WriteLine("\n >>>> To Find a Number is Palindrome or not <<<< ");
Console.Write("\n Enter a number: ");
num = Convert.ToInt32(Console.ReadLine());
temp = num;
while (Convert.ToBoolean(num))
{
rem = num % 10; //for getting remainder by dividing with 10
num = num / 10; //for getting quotient by dividing with 10
sum = sum * 10 + rem; /*multiplying the sum with 10 and adding
remainder*/
}
Console.WriteLine("\n The Reversed Number is: {0} \n", sum);
if (temp == sum) //checking whether the reversed number is equal to entered number
{
Console.WriteLine("\n Number is Palindrome \n\n");
}
else
{
Console.WriteLine("\n Number is not a palindrome \n\n");
}
Console.ReadLine();
Any sort of help is much appreciated!! Thank You :)
I'm not sure what you're asking, since the second snippet of code you found online should fix your issue.
Your code works, if you just change the line
newnum = remainder;
to
newnum = (newnum*10) + remainder;
The issue in your case is not the condition you used in the for loop, it's just that you're overwriting newnum with the remainder every time, so newnum is only storing the last reminder that was calculated in the loop, "forgetting" all the others it had calculated before.
To reverse the number, every time you enter the loop, you should add the last remainder you've found to the right of newnum, which is effectively equivalent to multiplying everything by 10 and adding remainder.
Try to follow it step by step with pen and paper (or with a debugger).
public bool isPalindome(int num)
{
string sNum = num.ToString();
for (int i = 0; i<sNum.Length; i++)
if (sNum[i] != sNum[sNum.Length-1-i]) return false;
return true;
}
I think that will do it... Untested!!
As dognose (and Eren) correctly assert you only need to go halfway through
public bool isPalindome(int num)
{
string sNum = num.ToString();
for (int i = 0; i < sNum.Length/2; i++)
if (sNum[i] != sNum[sNum.Length-1-i]) return false;
return true;
}
You will also need to decide what happend to negative numbers.. ie is -121 a plaindome? This method will say that it isn't...
Easiest way:
public static Boolean isPalindrom(Int32 number){
char[] n1 = number.ToString().ToCharArray();
char[] n2 = number.ToString().ToCharArray();
Array.Reverse(n2);
String s1 = new String(n1);
String s2 = new String(n2);
return (s1 == s2);
}
https://dotnetfiddle.net/HQduT5
you could also use Integers for s1 and s2 and return (s1-s2 == 0)
You have many ways of accomplish this exercise.
A. You can leave the input as string and loop it over, every iteration to check if the value of index 'i' and value of index 'len-i-1' are equals, if not false, otherwise return at the end of the loop true. (the loop should run till i < len/2)
B. You can create a new string and insert the text from end to start and then compare if the original string and result string are equals.
C. there are much more ways without using the string solutions, just with calculation..
int x;
cin<<x; //input the number
int ar[];
int i=0;
temp2=0;
while(x/10 != 0)
{
int temp=x%10;
ar[i]=temp;
x=x/10;
i++;
}
for(int j=0, j<i,j++)
{
temp2=temp2*10+ar[j];
}
if(temp2==x){cout<<"palindrome"}
else {"not palindrome"}
ok here is the logic:
we first input the number x(it can be of any length)..Next we split the number into array..the condition to do this is tha we check for the qoutient to decide whether the number is fully split..next we take the array and rejoin it and check with the input number..
Use the following code:
public boolean isPalindrom(Integer number)
{
return number.Equals(int.Parse(String.Join("", String.Join("", number.ToString().ToCharArray().Reverse().ToArray()))));
}