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());
}
Related
Alright so my problem here is I'm trying to create a user input array, and notify console if a specific data point is in the user input array. I realize you can see that the data point is there on the console, but I've been asked to do this and I don't ask why :'D.
public static void Main()
{
double [] array= new double [10]
double temp;
Console.WriteLine("Insert 10 numbers");
for (int i = 0; i < array.Length; i++)
{
array[i] = Convert.ToDouble(Console.ReadLine());
}
Console.WriteLine("What number do you wish to find?");
temp = Convert.ToDouble(Console.ReadLine());
foreach (int i in array)
{
if (temp == i)
{
Console.WriteLine("The number is in the array.")
break;
}
else if (temp != i)
{
Console.WriteLine("The number is not part of the array.");
break;
}
}
}
The output is: if you put the number that was in the first slot, it would come out as "The number is in the array", any other number that is part of the array will out put "The number is not part of the array" . If you remove the breaks in the If and Else if codes, the list will tell you one by one if the number is or is not part of the array.
How do I make it that it reads the entire array, and tells me that whatever number is part of the array?
Note I've been asked not to use LINQ nor the Array. objects
You should not check for temp != i, but == only within the loop:
// array is double[] - item is double
foreach (double item in array) {
// item found, we shall report and exit the method
if (item == temp) { // <- dubious: we should check doubles with tolerance
Console.WriteLine("The number is in the array.");
return; // <- not break
}
}
// entire array has been scanned, no item found
Console.WriteLine("The number is not part of the array.");
If you don't want to return, but insist on break:
bool inTheArray = false;
foreach (double item in array)
if (item == test) {
inTheArray = true;
break;
}
Console.WriteLine(inTheArray
? "The number is in the array."
: "The number is not part of the array.");
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.
I'm working on an application that has the user choose how many integers to enter into an array, and then has them input the numbers to be added to the array. After each number is inputted, it shows all non-duplicate integers entered by the user up to that point in a vertical list. If it isn't unique, it informs the user that it has already been inputted.
I'm not sure how to make the application list every integer entered, rather than just the most recent one.
Here's my code:
static void Main(string[] args)
{
//checks how many numbers will be entered
int manyNumbers;
Console.WriteLine("How many numbers will you enter?");
manyNumbers = Convert.ToInt32(Console.ReadLine());
int[] array = new int[manyNumbers];
//starts asking for numbers
for (int i = 0; i < manyNumbers;)
{
Console.Write("\nEnter number: ");
string entered = Console.ReadLine();
int val;
//checks to see if valid number
if (!Int32.TryParse(entered, out val))
{
Console.Write("Invalid number '{0}'", entered);
array[i++] = val;
}
//checks to see if already entered
else if (i > 0 && array.Take(i).Contains(val))
{
Console.Write("{0} has already been entered", val);
array[i++] = val;
}
//prints inputted integer
else {
array[i++] = val;
Console.WriteLine("{0}", val);
}
}
}
Just loop over the array so far printing each.
Forgive my mobile crafted code, but more or less this:
//prints inputted integer
else {
array[i++] = val;
for(int j=0 ; j<i;j++) {
Console.WriteLine("{0}", array[j]);
}
}
You may use foreach loop
foreach(int num in array)
{
Console.WriteLine("{0}", num);
}
Very Basic approach, try one of the following:
for(var x=0;x<array.length;x++)
or
foreach(var i in array)
But your use case, use HashSet data structure
Mathematically, Set is unique list of things.
try this code, it uses a Dictionary to keep the list in memory and to search to see if the an integer has been added,
using System.Collections.Generic;
static void Main(string[] args)
{
//checks how many numbers will be entered
int manyNumbers;
Console.WriteLine("How many numbers will you enter?");
manyNumbers = Convert.ToInt32(Console.ReadLine());
Dictionary<int, int> array = new Dictionary<int, int>();
//starts asking for numbers
for (int i = 0; i < manyNumbers; )
{
Console.Write("\nEnter number: ");
string entered = Console.ReadLine();
int val;
//checks to see if valid number
if (!Int32.TryParse(entered, out val))
{
Console.Write("Invalid number '{0}'", entered);
}
//checks to see if already entered
else
if (i > 0 && array.ContainsKey(val))
{
Console.Write("{0} has already been entered", val);
//array[i++] = val;
}
else
{
//* add the new integer to list
array.Add(val, 0);
//prints the complete list
List<int> keys = new List<int>(array.Keys);
Console.WriteLine();
for(int j=0; j<keys.Count; j++) Console.WriteLine(keys[j]);
}
}
}
I am having trouble copying data from inside a do--while loop and repeating it outside the loop. It is during a split function, where each student's test score is entered on the same line as his/her name. I'm sorry if this is a very simple question but I cannot find anywhere how to fix it. Thanks very much for any help.
do {
Console.Write("Enter the student's name followed by his/her score on the same line:");
studentAndScore = Console.ReadLine();
if (studentAndScore == "")
{
break;
}
string[] parsedInput;
parsedInput = studentAndScore.Split();
string student = parsedInput[0] = students[0];
score = int.Parse(parsedInput[1]);
score = studentScores[0];
i++;
} while (i<=MAX);
Console.WriteLine("The test scores of the students are:");
Console.WriteLine("students \t scores \t");
//And I need to repeat the list of student names and scores here
This line of code:
string student = parsedInput[0] = students[0];
is going to copy students[0] into parsedInput[0] first. So you're losing your parsed input.
Instead, try:
string student = parsedInput[0];
students[0] = student;
If that is, in fact, your intent. It's seldom a good idea to do two assignments in the same line of code.
It is likely that you really want to use i instead of 0 in your indexers, as in parsedInput[i] and students[i].
Just create two lists...
var names = new List<String>();
var scores = new List<Int32>();
...read the input into the lists...
while (true)
{
Console.Write("student/score: ");
var input = Console.ReadLine();
if (String.IsNullOrWhiteSpace(input))
{
var parts = input.Split();
names.Add(parts[0]);
scores.Add(Int32.Parse(parts[1]);
}
else
{
break;
}
}
... and output the lists.
for (var i = 0; i < names.Count; i++)
{
Console.WriteLine("{0}\t{1}", names[i], scores[i]);
}
And of course add a lot of error handling. Or you could use a dictionary but I am not really sure about the guarantees you get regarding the ordering of the items.
var data = new Dictionary<String, Int32>();
while (true)
{
Console.Write("student/score: ");
var input = Console.ReadLine();
if (String.IsNullOrWhiteSpace(input))
{
var parts = input.Split();
data.Add(parts[0], Int32.Parse(parts[1]));
}
else
{
break;
}
}
foreach (var entry in data)
{
Console.WriteLine("{0}\t{1}", entry.Key, entry.Value);
}
What Robert wrote is true. Additionally, you don't use the loop variable i to store each student in a different "slot" of the array, so you're overwriting everything currently in the same place. And the declaration of the array must be outside of the loop, otherwise it will erase it in each iteration.
Summing up the changes required to your C# code sample, the corrected version looks like this:
void Main()
{
int MAX = 20;
var students = new string[MAX];
var scores = new int[MAX];
int i=0;
do {
Console.Write("Enter the student's name followed by his/her score on the same line:");
var studentAndScore = Console.ReadLine();
if (studentAndScore == "")
{
break;
}
string[] parsedInput = studentAndScore.Split();
students[i] = parsedInput[0];
scores[i] = int.Parse(parsedInput[1]);
i++;
} while (i<MAX);
Console.WriteLine("The test scores of the students are:");
Console.WriteLine("students \t scores \t");
for(int k=0; k<i; k++) {
Console.WriteLine("Student: {0}, Score: {1}", students[k], scores[k]);
}
}
Note that I am using the value of i in the for statement rather than MAX, because the user can break out of the do loop by entering a blank line. And i always contains the # of items, which have been entered previously.
Of course, this code does not yet contain any error handling, which would be required in the real world.