C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Lan_Party

BIOS-Overclocker(in)
C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Moinsen erstmal,
also in der Schule haben wir ein Programm geschrieben um unsere Noten auszurechnen. Ich bin relativ weit gekommen nur jetzt habe ich das Problem das ich nicht mehr weis wie ich den Durchschnitt, beste Note etc. ausrechnen soll. Ich denke hier gibt es ein paar begabte C# Programmierer gibt die mir weiterhelfen können. :D Vllt. könntet ihr das Programm auch verbessern da wenn man die Noten eingibt etwa so:
1
2
3
1
[leerzeichen]
kommt eine Fehlermeldung. Man darf nach der 1 kein Enter mehr betätigen sonst Stürzt das Programm ab leider weis ich aber nicht wieso.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
// Deklaration der Variablen
Double dSumme, dDurchschnitt;

Double[] ar_dEingegebeneZahlen;

// Aufteilen der textbox in einzelne Zeilen
String[] ar_Zeile = Regex.Split(this.textBox1.Text, "\r\n");

ar_dEingegebeneZahlen = new Double[ar_Zeile.Length];

// Umwandeln der Textzeilen in Zahlen
for (int iL1 = 0; iL1 < ar_Zeile.Length; iL1++)
{
ar_dEingegebeneZahlen[iL1] = Convert.ToDouble(ar_Zeile[iL1]);
}
for (int iL1 = 0; iL1 < ar_Zeile.Length; iL1++)
{
MessageBox.Show(Convert.ToString(ar_dEingegebeneZahlen[iL1]));
}

//Summenschleife
if (this.radioButton1.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];
}
MessageBox.Show("Summe: " + Convert.ToString(dSumme));
}
else if (this.radioButton2.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];
}
MessageBox.Show("Durchschnitt: " + Convert.ToString(dSumme));
}
else if (this.radioButton3.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];
}
MessageBox.Show("Beste Note: " + Convert.ToString(dSumme));
}
else if (this.radioButton4.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];
}
MessageBox.Show("Schlechteste Note: " + Convert.ToString(dSumme));
}
}

private void radioButton1_CheckedChanged(object sender, EventArgs e)
{

}
}
}
 

Anhänge

  • Prog.png
    Prog.png
    7,6 KB · Aufrufe: 234
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Dein Programm stürzt genau hier ab:

ar_dEingegebeneZahlen[iL1] = Convert.ToDouble(ar_Zeile[iL1]);

Der eingegebene String wird am Enter ("\r\n") gesplittet. Wenn am Ende noch ein Enter folgt, ist das letzte Element des String-Arrays null oder mindestens Leerstring (String.Empty).
Die Convert.ToDouble verträgt diese Werte aber nicht und wirft gnadenlos eine Exception.
Daher sollte die obige Zeile in ein try-catch gekapselt werden und der catch-Block sollte die InvalidCastException abfangen:

try
{
ar_dEingegebeneZahlen[iL1] = Convert.ToDouble(ar_Zeile[iL1]);
}
catch(InvalidCastException ex)
{

}

Besser wäre es, beim Splitten des Strings die Split-Methode des Strings selbst zu benutzen, da hier über die
StringSplitOptions.RemoveEmptyEntries die leeren Einträge gleich eliminiert werden.

String[] ar_Zeile = this.textBox1.Text.Split("\r\n", StringSplitOptions.RemoveEmptyEntries);


Ganz allgemein noch der Tip, den ganzen Code in den EventHandler des Buttons zu packen ist ganz schlechter Programmierstil und
wenig wartungsfreundlich. Erstelle lieber für jede Berechnung eine definierte Methode mit Eingangs- und Ausgangsparametern, die dann in
den EventHandlern aufgerufen werden. Idealerweise in einer extra Klasse als Businesslayer (Stichwort 3-Layer- oder 3-Tier-Architektur).

Falls später die Oberfläche umgebaut wird, minimiert sich der Änderungsaufwand für den eigentlichen Funktionscode.
 
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Also jetzt ohne den Code angesehen zu habe wäre es wohl einfacher, wenn du die Noten einfach mit ";" trennst oder "," oder so. Dann kannst du beim Klick auf den Button folgendes machen:

Code:
     String[] meineNotenStr = textBox1.Text.Split(',') //oder eben ein anderes Trennzeichen.
     int[] meineNotenInt = new int[meineNotenStr.Length];
     for (int i=0; i<meineNotenStr.Length; i++)
         meineNotenInt = System.Convert.ToInt32(meineNotenStr [i]); //oder hier einen anderen Datentyp wählen
Tjo und dann für die Verschiedenen CheckBoxen:

  • Durchschnitt einfach den normalen Durchschnitt berechnen
  • Beste Note einfach den kleinsten Wert im int-Array suchen
  • Schlechteste Note einfach den größten Wert im int-Array suchen
  • Gesamtnote einfach nur Durchschnitt ausgeben, oder wenn die Noten noch eine Gewichtung haben (z.B. mit # oder sonstwas von Noten getrennt oder wie auch so mit \r\n (--> Sicherer ist System.Environment.Newline ;) ) noch die Gewichtung mit in die Durchschnittsrechnung mit einbeziehen, dann könnte die normale Durchschnittsberechnung als Gewichtung für alle noten einfach eine 1 haben)
ich denke mal, das schaffst du dann auch so :daumen:
Ansonsten frag einfach nochmal nach^^

Edit: Für die Summe und Schnitt müsstest du dann eine double (oder float) Variable nutzen, aber so die Noten (oder später die Punkte 0-15) können besser mit int gehandhabt werden
 
Zuletzt bearbeitet:
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Ich habe das alles einfach mal so übernommen nun kommen aber diese Fehlermeldungen und das Programm stürzt trotzdem ab.

Fehler 1 Die beste Übereinstimmung für die überladene string.Split(string[], System.StringSplitOptions)-Methode hat einige ungültige Argumente. H:\Zeugniss_Rechner\Zeugniss_Rechner\Form1.cs 28 33 Zeugniss_Rechner

Fehler 2 1-Argument: Kann nicht von "string" in "string[]" konvertiert werden. H:\Zeugniss_Rechner\Zeugniss_Rechner\Form1.cs 28 58 Zeugniss_Rechner

Das mit diesem Businesslayer hat uns unser Lehrer nie gezeigt. C# wird an unserer Schule jetzt erst Unterrichtet. Der Lehrer kennt sich dort noch nicht gut aus und staunt manchmal selbst was dort alles möglich ist. Das sollte ich mir mal genauer angucken da ich mir das mal kurz durchgelesen habe. Leider habe ich nicht viel im Inet gefunden und verstehen tue ich es auch nicht wirklich. Ich schaue mir es einfach mal genauer an.

BTW: Danke erstmal für deine Hilfe! :daumen:
 
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Achja die StringSplitOptions ... öhm, da sollte irgendwie Default reichen, auswendig kann ich die auch nicht, aber ich nehme immer das, was auch die leeren einträge gleich mit löscht.
Kann sonst im Laufe des Abends mal etwas machen ;)
Aber nun kommt erstmal PIIIZZAAAAAA :D
 
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Neuer Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
// Deklaration der Variablen
Double dSumme, dDurchschnitt;

// Aufteilen der textbox in einzelne Zeilen
String[] ar_Zeile = textBox1.Text.Split(',', System.StringSplitOptions.RemoveEmptyEntries);

int[] ar_dEingegebeneZahlen = new int[ar_Zeile.Length];

// Umwandeln der Textzeilen in Zahlen
for (int iL1 = 0; iL1 < ar_Zeile.Length; iL1++)
try
{
ar_dEingegebeneZahlen[iL1] = Convert.ToInt16(ar_Zeile[iL1]);
}
catch(InvalidCastException ex)
{

}
for (int iL1 = 0; iL1 < ar_Zeile.Length; iL1++)
{
MessageBox.Show(Convert.ToString(ar_dEingegebeneZahlen[iL1]));
}

//Summenschleife
if (this.radioButton1.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];
}
MessageBox.Show("Summe: " + Convert.ToString(dSumme));
}
else if (this.radioButton2.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];
}
MessageBox.Show("Durchschnitt: " + Convert.ToString(dSumme));
}
else if (this.radioButton3.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];
}
MessageBox.Show("Beste Note: " + Convert.ToString(dSumme));
}
else if (this.radioButton4.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];
}
MessageBox.Show("Schlechteste Note: " + Convert.ToString(dSumme));
}
}

private void radioButton1_CheckedChanged(object sender, EventArgs e)
{

}
}
}
Immernoch am abstürzen. Try und Catch hilft auch nicht. Wie kommts!? Sonst hatte ich nie Probleme damit. :what:

BTW: Guten Appetit! :daumen: Danke erstmal für die Hilfe! :D
 
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Wegen der Fehlermeldungen, ändere den Aufruf von String.Split folgendermaßen:

String[] ar_Zeile = textBox1.Text.Split(new string[] {","}, System.StringSplitOptions.RemoveEmptyEntries)

Die Methode braucht ein Array mit den Trennzeichen.... (siehe auch: String.Split Method (String[], StringSplitOptions) (System))

Wenn er immer noch abstürzt wäre die Fehlermeldung nicth schlecht, ansonsten einfach mal debuggen.
Falls ihr das Visual Studio verwendet, einen Breakpoint auf der ersten Codezeile im Click-EventHandler des Buttons setzen (mit dem Cursor in die Zeile gehen und F9 drücken).
Dann das Programm ausführen (F10), die Daten eingeben und den Button betätigen. Kurze Zeit später sollte er an dieser Zeile die Ausführung stoppen.
Danach die Befehle nacheinander ausführen (F10) und schauen, wo er aussteigt. Im Normalfall zeigt er euch die Exception.
Bei Schleifen einfach einen Breakpoint nach der Schleife setzen und mit F5 weitergehen.

Bei Durchschauen des Codes ist mir die Stelle aufgefallen:

for (int iL1 = 0; iL1 < ar_Zeile.Length; iL1++)
try
{
ar_dEingegebeneZahlen[iL1] = Convert.ToInt16(ar_Zeile[iL1]);
}
catch(InvalidCastException ex)
{

}


Die Schleife hat keine Klammern. Damit ersetzen:

for (int iL1 = 0; iL1 < ar_Zeile.Length; iL1++)
{
try
{
ar_dEingegebeneZahlen[iL1] = Convert.ToInt16(ar_Zeile[iL1]);
}
catch(InvalidCastException ex)
{

}
}

Das gefährliche ist, wenn das Array ar_dEingegebeneZahlen nicht komplett gefüllt wird, greifen die nachfolgenden Befehle ins Leere und es kommt zu einer NullReference-Exception.
Die Ausgaben in den Schleifen lassen sich aber so absichern:

if(ar_dEingegebeneZa hlen[iL1] != null)
{
MessageBox.Show(Convert.ToString(ar_dEingegebeneZa hlen[iL1]));
}

Auch hier läuft der Convert.ToString Amok, wenn das Element null ist. Gleiches wäre auch, wenn Du direkt die ToString-Methode des Array-Elementes nutzt.
Methoden können nur an existierenden Objekten aufgerufen werden.

Für String-Ausgaben empfehle ich generell String.Format zu nehmen, die Methode ist hier wesentlich fehlertoleranter:

Statt:
MessageBox.Show("Beste Note: " + Convert.ToString(dSumme));

diesen Aufruf:
MessageBox.Show(String.Format("Beste Note: {0}",dSumme));

Das sollte die Probleme jetzt aber beheben. Check einfach alle Zeilen nochmal auf Convert.X Aufrufe und debugge ein bisschen.

Happy Coding.
 
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

So habs nun mal kurz in recht simpler Weise gemacht ;)
Projektdateien für MS Visual Studio und exe sind in der folgenden ZIP-Datei.

Anhang anzeigen 517646


Edit: hab sogar einen kleinen "Fehler" drin: Wenn man Beste Note anwählt und Gewichtungen angegeben hat, dann werden diese nicht beachtet ... naja, das ist dann deine Hausaufgabe :P
 
Zuletzt bearbeitet:
Wir haben heute SW(Software) gehabt anstatt DB(Datenbanken) deshalb bin ich eig. fertig. Ich werde später den Code vom Lehrer mal hochladen dann könnt ihr mal sehen wie er es hat. Das einzige was gefehlt hat war ein Seperator.
Danke euch für die Hilfe aber ich denke selbst den Code vom Lehrer könnt ihr verbessern. ;)
PS: Als Compiler nutzen wir VS C# 2010.

EDIT: Hier kommt der Code! Ich denke Ihr könnt noch etwas dran verbessern. ;)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;

namespace Zensurenrechner
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//Deklarationen
Double dSumme, dDurchschnitt, dMerker, dNotenzaehler;

Double[] ar_dEingegebeneZahlen;


//Aufteilen der textbox in einzelne Zeilen
//String[] ar_sZeile = Regex.Split(this.textBox1.Text, "\r\n", RegexOptions.);
//String[] ar_sZeile = this.textBox1.Text.Split new String[]{","}("\r\n",StringSplitOptions.RemoveEmptyEntries);
String[] ar_sSeparator = new String[3];
ar_sSeparator[0] = "\r\n";
ar_sSeparator[1] = ",";
ar_sSeparator[2] = " ";
String[] ar_sZeile = this.textBox1.Text.Split(ar_sSeparator,StringSplitOptions.RemoveEmptyEntries);


ar_dEingegebeneZahlen = new Double[ar_sZeile.Length];

//Umwandeln der TExtzeilen in Zahlen

for (int iL1 = 0; iL1 < ar_sZeile.Length; iL1++)
{
if (!(ar_sZeile[iL1] == ""))
{
ar_dEingegebeneZahlen[iL1] = Convert.ToDouble(ar_sZeile[iL1]);
}
}

// Summenschleife
if (this.radioButton1.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];

}
MessageBox.Show("Summe: " + Convert.ToString(dSumme));
}
else if (this.radioButton2.Checked == true)
{
dSumme = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
dSumme = dSumme + ar_dEingegebeneZahlen[iL1];
}

dDurchschnitt = dSumme / ar_dEingegebeneZahlen.Length;
MessageBox.Show("Durchschnitt: " + Convert.ToString(dDurchschnitt));

}
else if (this.radioButton3.Checked == true)
{
dMerker = 7;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
if (ar_dEingegebeneZahlen[iL1] < dMerker)
{
dMerker = ar_dEingegebeneZahlen[iL1];
}

}
dNotenzaehler = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
if (ar_dEingegebeneZahlen[iL1] == dMerker)
{
dNotenzaehler++;
}

}
MessageBox.Show("Beste Zensur: " + Convert.ToString(dMerker) + ", kommt " + Convert.ToString(dNotenzaehler) + " mal vor.");

}
else if (this.radioButton4.Checked == true)
{
dMerker = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
if (ar_dEingegebeneZahlen[iL1] > dMerker)
{
dMerker = ar_dEingegebeneZahlen[iL1];
}

}

dNotenzaehler = 0;
for (int iL1 = 0; iL1 < ar_dEingegebeneZahlen.Length; iL1++)
{
if (ar_dEingegebeneZahlen[iL1] == dMerker)
{
dNotenzaehler++;
}

}
MessageBox.Show("Schlechteste Zensur: " + Convert.ToString(dMerker) + ", kommt " + Convert.ToString(dNotenzaehler) + " mal vor.");



}
else
{
MessageBox.Show("Bitte Auswahl treffen!");
}

}
}
}
@ fadade Dein Rechner hat einen kleinen Fehler. Die beste Note ist eine 6 und die schlechteste eine 1, laut deinem Rechner. ;)
Danke trotzdem und ausführlich ist er auch noch! :daumen:
 
Zuletzt bearbeitet:
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Push! Da post editiert ich hoffe das geht i.O. :D Sonst könnte ein Mod diesen Post zum letzten editieren bzw. löschen und pushen. :D
 
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

jo der ist in der tat etwas "fehlerhaft" wobei das im prinzip gewollt ist, denn ich hab intern jetzt doch schon mit punkten gearbeitet, also 14P = 1 11P = 2 9P = 3 usw. und dann ist eben das größte auch die beste Note.
Da sollte ich vllt noch einen Modusschalter einbauen :D

Naja, ich schau mir erstmal so den Lehrercode an :devil:
 
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Achso! Das solltest du dann aber auch dazu schreiben. :D
Na da bin ich mal gespannt. :D
Mein Lehrer war erstaunt als er gesehen hat was ihr mir so für Tipps gegeben habt. "Wer nimmt sich so viel Zeit für sowas :what:"!?
Er meinte ich soll aufjedenfall daran weiterarbeiten und freut sich das ich mich endlich damit auseinandersetze. ^^
 
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Er meinte ich soll aufjedenfall daran weiterarbeiten und freut sich das ich mich endlich damit auseinandersetze.

Ist das sonst eine bekenntnis zur Faulheit? Klingt ein bisschen so :D:devil:

Neyney Spass beiseite ^^
aber erfahrungsgemäß motivieren die Sachen deutlich mehr, wenn man sie anschließend auch selber nutzen kann, also einen praktischen Nutzen hat.
Wenn du im Unterricht wieder ein paar Probleme aufgetischt bekommst, schau ich da auch immer gern mal drüber ;)


@Code:

  • hoffentlich werden einige Rechtschreibfehler nicht zur Gewohnheit :ugly:
  • was wollte er denn dort mit Regex anfangen? :huh:
  • ansonsten vom Prinzip her in Ordnung .... nur ein bisschen sehr anfällig für falsche Eingaben ^^ Probier mal "3 3 3 5 T 6 1 2 " oder sowas, also ein bisschen try-catch gehört da immer rein


Falls ihr ein paar mathematische Probleme einbauen wollt, dann schaut mal bei https://projecteuler.net/ vorbei ;)
 
Ich werde es morgen mal ausprobieren. In der Schule hat es jedenfalls geklappt.
Regex...hmm da muss ich nochmal schauen was er dort gemacht hat.
Könntest du mir Vllt. Das 3-Tier-System einfach und trotzdem ausführlich erklären wenn du es beherrscht?

Wenn man es kann macht es auch Spaß. ;) Jedenfalls ist es viel interessanter geworden. :D

Danke :D :daumen:
 
Zuletzt bearbeitet:
Das müsste es sein. Wird auch Businesslayer genannt.
Deckard-Cain hat etwas dazu gepostet aber iwi bin ich da voll durcheinander gekommen. :fresse:
 
AW: C# - Berechungsprgamm --> Suche Hilfe + Verbesserungsvorschläge

Hey,

Also wo lernt ihr das? Also diese Methode kommt mir sehr verwirrend vor.
Ich habe zwar schon lang nicht mehr mit Windows Forms gearbeitet, aber ich glaub da sollts genau so wie in WPF eine ListBox geben. (Dann fällt der blöde String Split Blödsinn mal weg.)

Summe:
foreach children in listbox
summe += convert toint32 children.text

Durchschnitt:
summe / count of children in listbox

Beste Note:
foreach children in listbox
int best = 6;
if(best > childen.text to int)
best = convert toint32 children.text
Schlechteste Note:
inverse Beste Note (also die if und int best hald 0)

Das wäre hald meine "anfängerfreundliche" Methode. Wobei ich nicht weiß ob ihr ListBoxes und foreach schleifen schon durchgenommen habt. Wenn du willst schreib ich dir das in Codeform auch nochmal.

Ach bei dem 4 Methoden Code ist es schwachsinnig schon zu trennen. Sowas lohnt sich erst dann wenn du über die 50 Methoden hinausschießt. Mit dem Backgroundcode ist man da schon relativ gut dran.

Das einzige was mich graust sind die "else if". :D Mach eine RadioButton Group und ein Switch. Glaub das sieht besser und Übersichtlicher aus. :)

Mit freundlichen Grüßen,
Frezy
 
Zurück