简体   繁体   中英

My partial array keeps adding the empty data C#

I'm new to C# and we need to create an array that can hold 100 scores. But it needs to also accept something smaller (txt file with numbers between 0-100). My issue is that even tho I add a txt file that has 50 scores, it will think there is another 50 'blank scores' and it will count those as 0. So when my code does the average, total, and lowest score, it will mess it up. My textbook isn't being very help with the answer.

    private double Total(double[] iArray)
    {
        double total = 0;
        total = iArray.Length;

        return total;
    }
    
    //Average test score 
    private double Average(double[] iArray)
    {
        double total = 0;
        double average;
        for (int index = 0; index < iArray.Length; index++)
        {
            total += iArray[index];//look into later 
        }
        average = (double)total / iArray.Length;
        return average;
    } //done

    //for hightest test score
    private double Highest(double[] iArray)
    {
        double highest = iArray[0];
        for (int index = 1; index < iArray.Length; index++)
        {
            if (iArray[index] > highest)
            {
                highest = iArray[index];
            }
        }
        return highest;

    } //done

    private double Lowest(double[] iArray)
    {
        double lowest = iArray[0];
        for (int index = 1; index < iArray.Length; index++)
        {
            if (iArray[index] < lowest)
            {
                lowest = iArray[index];
            }
        }

        return lowest;
    }//done

    private void addFileButton_Click(object sender, EventArgs e)
    {
        try
        {
            const int SIZE = 100;               //number of test 
            double[] scores = new Double[SIZE]; //array of the test scores
            int index = 0; //loop counter
            int count = 0;
            double highestScore;
            double lowestScore;
            double averageScore;
            double totalScore;

            //Asking user to open a file
            StreamReader inputFile;

            if (openFile.ShowDialog() == DialogResult.OK)
            {
                inputFile = File.OpenText(openFile.FileName);
                
                while (!inputFile.EndOfStream && count < scores.Length)//switching index to count
                {
                    scores[count] = int.Parse(inputFile.ReadLine());
                    count++;
                }

                inputFile.Close();

            }
            else
            {
                MessageBox.Show("Operation Canceled.");
            }

            

            //Display test scores
            for (index = 0; index < count; index++)
            {
                scoreListBox.Items.Add(scores[index].ToString());
            }
            


            //grabbing information 
            highestScore = Highest(scores);
            lowestScore = Lowest(scores);
            averageScore = Average(scores);
            totalScore = Total(scores);


            //display values 
            highesScoreLabel.Text = highestScore.ToString();
            lowestScoreLabel.Text = lowestScore.ToString();
            averageTestScoreLabel.Text = averageScore.ToString();
            totalTestScoresLabel.Text = totalScore.ToString();

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        
    }

You might just have to use Array.Resize then:

while (!inputFile.EndOfStream && scores.Count <= SIZE)
{
    scores.Add(int.Parse(inputFile.ReadLine()));
    count++;
}
Array.Resize(scores, count);

See if that works.


This was suggested before the OP's comment clarifying the should specifically use an array:

What if you used a List<double> when collecting the scores, then .ToArray() before you pass it into your other methods?

const int SIZE = 100;
List<double> scores = new List<double>();

[...]

if (openFile.ShowDialog() == DialogResult.OK)
{
    inputFile = File.OpenText(openFile.FileName);
    
    while (!inputFile.EndOfStream && scores.Count <= SIZE)
    {
        scores.Add(int.Parse(inputFile.ReadLine()));
        count++;
    }

    [...]

var arrScores = scores.ToArray();

//grabbing information 
highestScore = Highest(arrScores);
lowestScore = Lowest(arrScores);
averageScore = Average(arrScores);
totalScore = Total(arrScores);

Notice that the while loop has the condition changed for scores.Count <= SIZE to still only allow up to 100 scores.

Instead of constructing the Array yourself and implementing all these methods, I suggest, you read up in LINQ. LINQ stands for Language INtegrated Query and is essentially a bunch of extension methods on IEnumerable<T> that provide all of the functionality you need here.

I rewrote your event handler to use LINQ and it became much simpler.

private void addFileButton_Click(object sender, EventArgs e)
{
    try
    {
        // Easier to follow if we just exit early
        if (openFile.ShowDialog() != DialogResult.OK)
        {
            MessageBox.Show("Operation Canceled.");
            return;
        }
        
        var scores = File.ReadAllLines(openFile.FileName)
            // Always use TryParse to avoid exceptions
            .Select(l => int.TryParse(l, out var score) ? score : -1)
            // Filter out everything that is no valid score
            .Where(s => s >= 0)
            // You could also use ToList() here for a possible minimal performance gain and the possibility to add items later.
            .ToArray();

        // Display test scores
        // We are using foreach instead of for here because we do not care about indexes. We simply want to add each item.
        // We also do not need to add the ToString(), just adding an int is fine.
        foreach (var score in scores)
            scoreListBox.Items.Add(score);

        // grabbing information 
        // We use LINQ methods here. Microsoft was nice enough di implement a bunch of often used methods on collections for us.
        var highestScore = scores.Max();
        var lowestScore = scores.Min();
        var averageScore = scores.Average();
        var totalScore = scores.Sum();


        //display values 
        highesScoreLabel.Text = highestScore.ToString();
        lowestScoreLabel.Text = lowestScore.ToString();
        averageTestScoreLabel.Text = averageScore.ToString();
        totalTestScoresLabel.Text = totalScore.ToString();

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM