2016-04-14 10 views
1

Ich studiere bei TAFE, aber die Klasse und ich bekommen überhaupt keine Hilfe von meinem Dozenten.C# Textdatei lesen find min max durchschnittlich

Ich muss aus einer TXT-Datei lesen und die Min Max und Durchschnitt davon finden und es auf der Konsole ausdrucken.

Die vorherige Aufgabe war es, min max Durchschnitt von einem Array zu bekommen und ich habe dies geschrieben und es funktioniert gut. Ich benutze VS2012.

Ich habe den Code geschrieben, um die Textdatei zu lesen und auf die Konsole zu drucken - aber ich kann nicht die Min Max und Durchschnitt finden. Ich bekomme "Objektverweis nicht auf eine Instanz eines Objekts festgelegt." wenn ich das Programm starte.

Beachten Sie, dass ich den gleichen Code verwendet habe, um min max Durchschnitt von einem Array zu finden ... Ich denke, das könnte das Problem sein, aber ich kann es nicht herausfinden !!

Hier ist mein Code für das Array ...

 static void Main(string[] args) 
     { 
      int[] hoursArray = { 1, 24, 9, 7, 6, 12, 10, 11, 23, 8, 2, 9, 8, 8, 9, 7, 9, 15, 6, 1, 7, 6, 12, 10, 11, 23, 1, 2, 9, 8 }; 
      for (int i = 0; i < hoursArray.Length; i++) 
      { 
       Console.WriteLine(hoursArray[i].ToString()); 
      } 

      { 

       { 
        int low = hoursArray[0]; 
        for (int index = 1; index > hoursArray.Length; index++) 
        { 
         if (hoursArray[index] < low) 
         { 
          low = hoursArray[index]; 
         } 
        } 

        Console.WriteLine("Lowest Hours Parked = " + low); 

       int high = hoursArray[0]; 
       for (int index = 1; index < hoursArray.Length; index++) 
       { 
        if (hoursArray[index] > high) 
        { 
         high = hoursArray[index]; 
        } 
       } 

       Console.WriteLine("Highest Hours Parked = " + high); 

        int total = 0; 
        double average = 0; 
        for (int index = 0; index < hoursArray.Length; index++) 
        { 
         total = total + hoursArray[index]; 
        } 

        average = (double)total/hoursArray.Length; 
        Console.WriteLine("Average Hours Parked =" + average.ToString("N")); 

        Console.ReadLine(); 
       } 
      } 
     } 
    } 
} 

Wie erwähnt das funktioniert gut. Jetzt für mein Problem ... Ich habe den Code geschrieben, wie pro unten mit meinen Kommentaren, die Daten aus der Textdatei anzuzeigen ...

 static void Main(string[] args) 
    { 
     StreamReader hours = new StreamReader("hours.txt"); 
     string number = ""; 

     while (number != null) 
     { 
      number = hours.ReadLine(); 
      if (number != null) 
       Console.WriteLine(number); 
     } 
     //list of numbers above is all ok when running program 

     int total = 0; 
     double average = 0; 
     for (int index = 0; index < number.Length; index++) 
     { 
      total = total + number[index]; 
     } 
     average = (double)total/number.Length; 
     Console.WriteLine("Average = " + average.ToString("N2")); 

     int high = number[0]; 

     for (int index = 0; index < number.Length; index++) 
     { 
      if (number[index] > high) 
      { 
       high = number[index]; 
      } 
     } 

     Console.WriteLine("Highest number = " + high); 

     int low = number[0]; 

     for (int index = 0; index > number.Length; index++) 
     { 
      if (number[index] < low) 
      { 
       low = number[index]; 
      } 
     } 
     Console.WriteLine("Lowest number = " + low); 
     hours.Close(); 
       Console.ReadLine(); 
     } 
    } 
} 
+0

Das Problem in Ihrem zweiten Teil des Codes wird Sie in den Zahlen lesen, aber nicht speichern, sie überall, also nein, man kann sie benutzen, später. Sie lesen sie alle in der Zahl ein (vorausgesetzt, dass niemand in der Mitte Ihrer Datei einen cat geschrieben hat), aber Sie platzieren ihn dann nicht in ein Array oder eine Liste. Nehmen Sie dies als Hinweis und sehen Sie, ob dies Ihnen hilft – BugFinder

+0

Sie speichern nur die erste Zahl in einer String-Variablen und Sie durchlaufen die Zeichen dieser Zeichenfolge, um die Summe, High und Low zu berechnen. Erstellen Sie stattdessen eine Liste , und lesen Sie alle Zeilen, nicht nur die erste Zeile (die Bedingung in while sollte sich ändern), geben Sie die Zeichenfolge für jede Zeile in ganze Zahlen und speichern Sie die ganze Zahl in der Liste (oder einem Array). –

Antwort

0

Verwenden File.ReadLines den Inhalt der Datei zu lesen und dann diejenigen konvertieren int Array mit einfachen Linq Anweisungen.

int[] hoursArray = File 
    .ReadLines("filepath") // Read all lines, 
    .SelectMany(s => s.Split(",").Select(int.Parse)) // Split by ',' and convert them to int. 
    .ToArray(); 

Sobald Sie dies tun, sollte der Rest des Codes so funktionieren wie es ist.

Noch ein Vorschlag, es gibt vordefinierte Methoden/Funktionen auf Array zu erhalten Average, Min und Max.

Sie könnten einfach tun.

var avg = hoursArray.Average(); 
var min = hoursArray.Min(); 
var max = hoursArray.Max(); 
+0

'File.ReadLines' anstelle von' File.ReadAllLines' normalerweise eine bessere Wahl –

+0

Das stimmt, für große Dateien wird immer empfohlen 'File.ReadLines' zu verwenden. Danke @DmitryBychenko –

+0

Obwohl der Code kürzer ist, ist die von @Dmitry Bychenko zur Verfügung gestellte Lösung schneller, da nur eine Schleife benötigt wird. – Abbas

0
string text = System.IO.File.ReadAllText("filePath"); 
     int[] hoursArray = (text.Split(' ').ToArray()).Select(x => Convert.ToInt32(x)).ToArray(); 
     int max = hoursArray.Max(); 
     int min = hoursArray.Min(); 
     double avg = hoursArray.Average(); 
+0

Obwohl der LinQ-Code kürzer ist, ist die Lösung von @Dmitry Bychenko schneller, da nur eine Schleife benötigt wird. – Abbas

3

Ich schlage vor, mit Linq:

// First of all define the source - it can be an array, file - whatever: 
// var source = hoursArray; // e.g. source for the array 
var source = File 
    .ReadLines(@"C:\MyFile.txt")   //TODO: put actual file here 
    .SelectMany(line => line.Split(',')) //TODO: put actual separator here 
    .Select(item => int.Parse(item)); 

// having got source (IEnumerable<int>) let's compute min, max, average 

int max = 0; 
int min = 0; 
double sum = 0.0; // to prevent integer division: 7/2 = 3 when 7.0/2 = 3.5 
int count = 0; 
boolean firstItem = true; 

foreach (item in source) { 
    sum += item; 
    count += 1; 

    if (firstItem) { 
    firstItem = false; 
    max = item; 
    min = item; 
    } 
    else if (item > max) 
    max = item; 
    else if (item < min) 
    min = item; 
} 

// Finally, formatted output 
Console.Write("Min = {0}; Max = {1}; Average = {2}", min, max, sum/count); 
+0

Dies ist die richtige Antwort imo. – Abbas