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.
Related
I’m new to programming and I’m trying to write a code that does this:
Entry data
Name 1
Time 1
Name 2
Time 2
Output
Show the name that has the best time.
Now, I’ve managed to create a code that shows the correct result if I write the entry data like this:
A
200
B
300
(numbers are random)
Here is what I have tried so far -
string inputdata = Console.ReadLine();
char name = Convert.ToChar(inputdata);
inputdata = Console.ReadLine();
double time1 = Convert.ToDouble(inputdata);
inputdata = Console.ReadLine();
char name2 = Convert.ToChar(inputdata);
inputdata = Console.ReadLine();
double time2 = Convert.ToDouble(inputdata);
inputdata = Console.ReadLine();
if (time1 < time2) { Console.WriteLine(name); }
else { Console.WriteLine(name2);
I don’t know how to type into the console the full name (any full word) so I don’t get “String must be exactly one character long”.
I’ve been strugling a bit with this and can’t seem to find the right answer.
Thank you!
I think that this should do the trick.
Here is the link so you can try it out.
Console.WriteLine ("Name 1: ");
string name1 = Console.ReadLine(); //put name into a string, so we can use it after
Console.WriteLine ("Time 1: ");
int time1 = Convert.ToInt32(Console.ReadLine()); //put time into an int, so we can see who has better time
Console.WriteLine ("Name 2: ");
string name2 = Console.ReadLine();
Console.WriteLine ("Time 2: ");
int time2 = Convert.ToInt32(Console.ReadLine());
if(time1 > time2) //checking who has better time
Console.WriteLine(name1 + " has the better time."); //writing the name with the message
else if(time1 < time2)
Console.WriteLine(name2 + " has the better time.");
else
Console.WriteLine(name1 + " and " + name2 + " have the same time");
To read full word you must use Console.ReadLine (Reads the next line of characters from the standard input stream). To better data representation you need to introduce some class or struct that contains Name and Time. I add example according to your input data but if you want to add arbitrary number of elements than it's better to use List instead of array and do-while loop instead of for loop
public class Sprinter
{
public string Name { get; set; }
public int Time { get; set; }
}
...
//Define array
var results = new Sprinter[2];
// Load data
for (var index = 0; index < results.Length; index++)
{
results[index] = new Sprinter();
results[index].Name = Console.ReadLine();
results[index].Time = int.Parse(Console.ReadLine() ?? "0");
}
//Find minimum
var minTime = int.MaxValue;
Sprinter minElement = null;
for (var index = 0; index < results.Length; index++)
{
var sprinter = results[index];
if (sprinter.Time < minTime)
{
minElement = sprinter;
minTime = sprinter.Time;
}
}
//Show minimum
Console.WriteLine($"Min is {minElement.Name} with time {minElement.Time}");
Output:
Foo
200
Bar
300
Min is Foo with time 200
i did write , but it gets just the nam:
var namenListe = new List<string>();
while(true)
{
Console.WriteLine("Geben Sie die Namen ein ; ");
string name = Console.ReadLine();
Console.WriteLine("Die namen : ");
namenListe.Add(name);
for (int i = 0; i < namenListe.Count; i++)
{
Console.WriteLine(namenListe);
}
private static readonly Random random = new();
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Enter a set of comma separated name here:");
var names = Console.ReadLine();
if (string.IsNullOrWhiteSpace(names))
{
Console.WriteLine("Bad name input, try again \n");
continue;
}
Console.WriteLine("Enter number of randomly selcted named:");
var count = Console.ReadLine();
if (!int.TryParse(count, out var nameCount))
{
Console.WriteLine("Bad name count input, try again \n");
continue;
}
// Split the names.
var nameCollection = names.Split(',', StringSplitOptions.TrimEntries).ToList();
// Shuffle names.
nameCollection = nameCollection.OrderBy(_ => random.Next()).ToList();
Console.WriteLine($"Your randomly selected {nameCount} names are : {string.Join(", ", nameCollection.Take(nameCount))}\n\n");
}
}
I think you will need to create a random number in a range from your minimum desired number of names to your maximum, then Use that to determine whether or not a name gets printed.. Like if your random number is five.. int x=0; if (x<ran) {print name(); x++;} If (x==ran) return; run this kind of code in your for loop instead of just printing all names.. But you'll have to generate your own random number.. the code is something like. int ran; ran =Random %max *100 +minimum; You'll have to check to be sure. And include Math.h or some other header to make sure random works.
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());
}
I'm struggling to find a way to first
Get User input to decide how many elements will be in the next string array
Then to convert the Users input from string to int for the array
Is there also a way to display the element number along with the string element like so.... Console.WriteLine(1. StringName 2.StringName);
This is my code :
Console.WriteLine("How many countries you want mate ? ");
string numberOfCountries = Console.ReadLine();
Console.WriteLine("Please name your countries ");
string[] nameOfCountries = new string[10];
for (int i = 0; i < nameOfCountries.Length ; i++)
{
nameOfCountries[i] = Console.ReadLine();
}
Get User input to decide how many elements will be in the next string array
You can put a variable in when creating an array size, like this:
string[] nameOfCountries = new string[someVariable];
someVariable needs to be an int. Console.WriteLine returns a string, so you need to parse the string to an int. You can use int.Parse for that. So:
int numberOfCountries = int.Parse(Console.ReadLine());
string[] nameOfCountries = new string[numberOfCountries];
Note that Parse will throw an exception if it isn't able to correctly parse the input in to an integer.
Is there also a way to display the element number along with the string element
You can use a similar loop like you are when you are assigning values to the array.
Console.WriteLine("{0}: {1}", i, nameOfCountries[i]);
Program:
string mate = "mate";
Console.WriteLine($"How many countries you want {mate}?");
string numberOfCountries = Console.ReadLine();
int numberOfCountriesInt;
while ( !int.TryParse( numberOfCountries, out numberOfCountriesInt ) )
{
mate = mate.Insert(1, "a");
Console.WriteLine($"How many countries you want {mate}?");
numberOfCountries = Console.ReadLine();
}
Console.WriteLine("Please name your countries ");
string[] namesOfCountries = new string[numberOfCountriesInt];
for (int i = 0; i < namesOfCountries.Length; i++)
{
namesOfCountries[i] = Console.ReadLine();
}
for (int i = 0; i < namesOfCountries.Length; i++)
{
Console.WriteLine($"{i+1}, {namesOfCountries[i]}");
}
Output:
How many countries you want mate?
Two
How many countries you want maate?
Two?
How many countries you want maaate?
2
Please name your countries
Stralya
PNG
1. Stralya
2. PNG
Please note that a List<string> may be better to store data like this. Then you can do something like this:
Console.WriteLine("Please name your countries ");
var namesOfCountries = new List<string>();
for (int i = 0; i < numberOfCountriesInt; i++)
{
namesOfCountries.Add(Console.ReadLine());
}
I'm starting with the C# language making console "apps". This one is to make grade averages. It doesn't show each name on each line with its own average that I still have to code. It works 100% until the //notation I've put
on the code. Under that I think it's the main problem, something that I might have forgotten to add or something.
namespace Repeat
{
class Program
{
static void Main(string[] args)
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("grade averages\n");
Console.ResetColor();
Console.WriteLine("");
float studentNumber;
float testNumber;
string name = "0";
string test;
float average = 0;
Console.WriteLine("Type the student number");
float.TryParse(Console.ReadLine(), out studentNumber);
Console.WriteLine("Type the number of tests");
float.TryParse(Console.ReadLine(), out testNumber);
Console.WriteLine("");
for (int a = 1; a <= studentNumber; a++)
{
Console.WriteLine("Type the student name " + a + ":");
nome = Console.ReadLine();
for (int p = 1; p <= testNumber; p++)
{
Console.WriteLine("Type the grade of test " + p + ":");
prova = Console.ReadLine();
}
Console.WriteLine("");
}
//All above is working 100%
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Students average:");
Console.ResetColor();
Console.WriteLine("");
for (int a = 1; a <= studentNumber; a++)
{
Console.WriteLine(name + ":" + average);
}
Console.ReadKey();
}
}
}
Every time you read the names and test-results of the students, you overwrite the previous value. You should store the names and grades (and possibly do some averaging-calculations). One example would be to use a Dictionary<string,List<int>> or Dictionary<string,List<string>>, where the name is stored in the Key, and the grades are stored as a list in the Value.
The Dictionary class is from the namespace System.Collections.Generic.
Here is the documentation for the Dictionary.
You're entering the names of the students and the test scores, but you need to save those values somewhere so that you can display them again.
This is just a basic example. You could add another class to your project like this:
public class StudentScoreCollection
{
private List<float>() _testScores = new List<float>();
public string StudentName {get;set;}
public List<float> TestScores {get{return _scores}}
}
Then, in your main program, declare a variable like
var scores = new List<StudentScoreCollection>();
Each time you start with a new student name (inside the first for loop)
declare
var score = new StudentScore();
score.Name = Console.ReadLine();
Then as each score is entered,
score.TestScores.Add(float.Parse(Console.ReadLine());
(There's no validation here - it will blow up if they enter something that isn't a number.)
Then at the end,
scores.ForEach(score => Console.WriteLine(score.name + score.TestScores.Average());
I wrote that as a LINQ expression. That can be confusing at first. It's more readable as a for-each loop. This is the exact same thing:
foreach(var score in scores)
{
Console.WriteLine(score.name + score.TestScores.Average();
}
Once you create a class that represents data that logically belongs together - like a name and a list of related scores - the rest becomes a little easier to work with.