Erstellen Sie eine Struktur zum Speichern der Studentendaten und führen Sie eine statistische Analyse der Daten durch

100577
Duck

Ich musste ein Programm erstellen, das eine Struktur mit Daten enthielt. Ich musste eine Eingabedatei lesen und den Inhalt nehmen und in ein Array von Strukturen einlesen. Dann musste ich nach bestimmten statistischen Daten suchen, beispielsweise nach den niedrigsten und höchsten Werten der Daten. Ich habe meinen Quellcode fertiggestellt und er läuft und gibt mir die korrekte Ausgabe, aber ich hätte gerne eine zweite Meinung. Bitte beachten Sie, dass die Kommentare für mich persönlich sind. Obwohl der Quellcode den Lesern leicht zu verstehen gibt, was los ist, habe ich sie hinzugefügt, um mir dabei zu helfen, organisiert zu bleiben.

Die Anweisungen für die Zuordnung finden Sie unten:

Schreiben Sie mit Hilfe der funktionalen Zerlegung ein Programm, um Aufzeichnungen zu führen und statistische Analysen für eine Klasse von 9 Schülern durchzuführen. Während des Semesters finden 3 Prüfungen mit jeweils 100 Punkten statt. Jeder Student wird durch einen vierstelligen Studentenausweis mit Vorname und Nachname sowie drei Prüfungsnoten identifiziert.

Sie lesen die Eingabedaten aus der Eingabedatei Scores.txt (werden in Etudes veröffentlicht). und die Daten haben das Format (studentID, Vorname, Nachname, Prüfung1, Prüfung2 und Prüfung3).

Jede Datenzeile für einen Schüler wird aus der Datei gelesen und dann einer Strukturvariablen zugewiesen. Daher benötigen Sie ein Array von Strukturen, um alle aus der Eingabedatei gelesenen Daten zu speichern. Dies wird ein 1-dimensionales Array sein.

Nachdem Sie Daten aus der Datei in Ihr Array gelesen haben, müssen Sie die folgenden Statistiken für jede Untersuchung berechnen und anzeigen. Die Statistiken, die angezeigt werden, sind:

  • niedrigste Punktzahl

  • höchste Punktzahl.

  • durchschnittliche Punktzahl auf 2 Dezimalstellen gerundet.

  • Standardabweichung auf 2 Dezimalstellen gerundet.

Es ist besser, für jede Statistik der Größe 3 ein Array zu haben, d. H. Ein Array für niedrigste Werte usw.

Die oben genannten Werte für „xxx“ müssen anhand der bereitgestellten Daten berechnet werden. Sie können davon ausgehen, dass die Bewertungen der Datei überprüft wurden und alle gültig sind.

Zeigen Sie auch die Anzahl der Schüler an, wie oben auf der linken Seite jeder Reihe angegeben.

Die Note basiert auf der Summe aller 3 Prüfungen, die aus 300 bestehen, und die Note wird wie folgt sein:

Total Score Grade
270 or more A
240 to 269 B
210 to 239 C
180 to 209 D
179 or less F

Sie sollten auch eine Funktion haben, um das Ergebnis in aufsteigender Reihenfolge nach dem Nachnamen zu sortieren.

Eingabedatei:

1234 David Dalton 82 86 80
9138 Shirley Gross 90 98 94
3124 Cynthia Morley 87 84 82
4532 Albert Roberts 56 89 78
5678 Amelia Pauls 90 87 65
6134 Samson Smith 29 65 33
7874 Michael Garett 91 92 92
8026 Melissa Downey 74 75 89
9893 Gabe Yu 69 66 68

Erwartete Ausgabe (oder etwas Ähnliches):

Erstellen Sie eine Struktur zum Speichern der Studentendaten und führen Sie eine statistische Analyse der Daten durch

Meine Ausgabe:

Erstellen Sie eine Struktur zum Speichern der Studentendaten und führen Sie eine statistische Analyse der Daten durch

#include "stdafx.h"
#include <iostream> 
#include <string> 
#include <fstream>
#include <iomanip>
#include <cmath> 

using namespace std; 

struct StudentData
{
    int studentID; 
    string first_name; 
    string last_name; 
    int exam1; 
    int exam2; 
    int exam3; 
    int total; 
    char ch; 
}; 

const int SIZE = 9; 
const int INFO = 4; 

// Function prototypes
void openInputFile(ifstream &, string); 
void getTotal(StudentData[]); 
void getGrade(StudentData[]); 
void calcLowest(StudentData[], int &, int &, int &, int &, int[]);  
void calcHighest(StudentData[], int &, int &, int &, int &, int[]);  
void getAverage(StudentData[], int, double &, double &, double &, double &, double[]); 
void getStd(StudentData[], double &, double &, double &, double &, double &, double &, double &, double &, double[]); 
void print(StudentData[], int[], int[], double[], double[]); 
void sort(StudentData[]); 

int main()
{
    // Variables 
    StudentData arr[SIZE]; 
    int lowest1, lowest2, lowest3, lowest4; // Stores lowest exam scores
    int highest1, highest2, highest3, highest4; // Holds highest exam scores
    double average1 = 0, average2 = 0, average3 = 0, average4 = 0; // Represents average of each exam 
    double std1 = 0, std2 = 0, std3 = 0, std4 = 0; // Holds standard deviation for Exams 1-3 and Total 
    int lowest[INFO] = {};
    int highest[INFO] = {}; 
    double average[INFO] = {}; 
    double standardDeviation[INFO] = {}; 

    ifstream inFile; 
    string inFileName = "C:\\Users\\Lisa\\Desktop\\scores.txt"; 

    // Call function to read data in file
    openInputFile(inFile, inFileName);

    // Read data into an array of structs 
    for(int count = 0; count < SIZE; count++)
    {
        inFile >> arr[count].studentID >> arr[count].first_name >> arr[count].last_name >> arr[count].exam1 >> arr[count].exam2 >> arr[count].exam3; 
    }

    // Close input file
    inFile.close();  

    // Get score total for each student 
    getTotal(arr); 

    // Determine grade for each student
    getGrade(arr); 

    // Calculate lowest scores in each exam and total scores
    calcLowest(arr, lowest1, lowest2, lowest3, lowest4, lowest); 

    // Calculate highest scores in each exam and total scores  
    calcHighest(arr, highest1, highest2, highest3, highest4, highest); 

    // Calculate average of each exam and the average of the total scores
    getAverage(arr, SIZE, average1, average2, average3, average4, average); 

    // Calculate standard deviation of each category 
    getStd(arr, std1, std2, std3, std4, average1, average2, average3, average4, standardDeviation); 

    cout << "\n"; 

    // Print unsorted data
    print(arr, lowest, highest, average, standardDeviation); 

    cout << "\n"; 

    // Sort data 
    sort(arr); 

    // Print sorted data
    print(arr, lowest, highest, average, standardDeviation); 

    system("PAUSE"); 

    return 0; 
}

/**
* Pre-condition: 
* Post-condition: 
*/
void openInputFile(ifstream &inFile, string inFileName)
{
    //Open the file
    inFile.open(inFileName);

    //Input validation
    if (!inFile)
    {
        cout << "Error to open file." << endl;
        cout << endl;
        return;
    }
}

/**
* Pre-condition: 
* Post-condition: 
*/
void getTotal(StudentData arr[])
{
    for(int i = 0; i < SIZE; i++)
    {
        arr[i].total = arr[i].exam1 + arr[i].exam2 + arr[i].exam3; 
    }
}

/**
* Pre-condition: 
* Post-condition: 
*/
void getGrade(StudentData arr[])
{
    for(int i = 0; i < SIZE; i++)
    {
        if(arr[i].total >= 270)
            arr[i].ch = 'A'; 
        else if(arr[i].total >= 240)
            arr[i].ch = 'B'; 
        else if(arr[i].total >= 210)
            arr[i].ch = 'C'; 
        else if(arr[i].total >= 180)
            arr[i].ch = 'D'; 
        else 
            arr[i].ch = 'F'; 
    }
}

/**
* Pre-condition: 
* Post-condition: 
*/
void calcLowest(StudentData arr[], int &lowest1, int &lowest2, int &lowest3, int &lowest4, int lowest[])
{
    int smallest = 0; 

    lowest1 = arr[0].exam1; 
    lowest2 = arr[0].exam2; 
    lowest3 = arr[0].exam3; 
    lowest4 = arr[0].total; 

    // Loop to determine lowest score from Exam1, 2, 3, and Total
    for (int i = 0; i < SIZE; i++)
    {
        if (lowest1 > arr[i].exam1)
        {
            lowest1 = arr[i].exam1; 
            smallest = i; 
        }

        if (lowest2 > arr[i].exam2)
        {
            lowest2 = arr[i].exam2; 
            smallest = i; 
        }

        if (lowest3 > arr[i].exam3)
        {
            lowest3 = arr[i].exam3; 
            smallest = i; 
        }

        if (lowest4 > arr[i].total)
        {
            lowest4 = arr[i].total; 
            smallest = i; 
        }
    }

    // Loop lowest values into an array of size 4 
    for(int index = 0; index < INFO; index++)
    {
        if(index == 0)
            lowest[0] = lowest1; 
        else if(index == 1)
            lowest[1] = lowest2; 
        else if(index == 2)
            lowest[2] = lowest3; 
        else if(index == 3)
            lowest[3] = lowest4; 
        else 
            cout << "Fail!" << endl; 
    }
}

/**
* Pre-condition: 
* Post-condition: 
*/
void calcHighest(StudentData arr[], int &highest1, int &highest2, int &highest3, int &highest4, int highest[])
{
    int biggest = 0; 

    highest1 = arr[0].exam1; 
    highest2 = arr[0].exam2; 
    highest3 = arr[0].exam3; 
    highest4 = arr[0].total; 

    // Loop to determine highest score from Exam1, 2, 3, and Total 
    for (int i = 0; i < SIZE; i++)
    {
        if (highest1 < arr[i].exam1)
        {
            highest1 = arr[i].exam1; 
            biggest = i; 
        }

        if (highest2 < arr[i].exam2)
        {
            highest2 = arr[i].exam2; 
            biggest = i; 
        }

        if (highest3 < arr[i].exam3)
        {
            highest3 = arr[i].exam3; 
            biggest = i; 
        }

        if (highest4 < arr[i].total)
        {
            highest4 = arr[i].total; 
            biggest = i; 
        }
    }

    // Loop highest values into an array of size 4 
    for(int index = 0; index < INFO; index++)
    {
        if(index == 0)
            highest[0] = highest1; 
        else if(index == 1)
            highest[1] = highest2; 
        else if(index == 2)
            highest[2] = highest3; 
        else if(index == 3)
            highest[3] = highest4; 
        else 
            cout << "Fail!" << endl; 
    }
}

/**
* Pre-condition: 
* Post-condition: 
*/
void getAverage(StudentData arr[], int size, double &average1, double &average2, double &average3, double &average4, double average[])
{
    int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0; 

    // Get sum of each category (Exam1, 2, 3, and Total)
    for(int i = 0; i < SIZE; i++)
    {
        sum1 += arr[i].exam1;
        sum2 += arr[i].exam2; 
        sum3 += arr[i].exam3;
        sum4 += arr[i].total; 
    }

    // Calculate average for each category 
    average1 += static_cast<double>(sum1)/size;  

    average2 += static_cast<double>(sum2)/size; 

    average3 += static_cast<double>(sum3)/size; 

    average4 += static_cast<double>(sum4)/size; 

    // Loop average values into an array of size 4 
    for(int index = 0; index < INFO; index++)
    {
        if(index == 0)
            average[0] = average1; 
        else if(index == 1)
            average[1] = average2; 
        else if(index == 2)
            average[2] = average3; 
        else if(index == 3)
            average[3] = average4; 
        else 
            cout << "Fail!" << endl; 
    }
}

/**
* Pre-condition: 
* Post-condition: 
*/
void getStd(StudentData arr[], double &std1, double &std2, double &std3, double &std4, double &average1, double &average2, double &average3, double &average4, double standardDeviation[])
{
    double deviationSum1 = 0, deviationSum2 = 0, deviationSum3 = 0, deviationSum4 = 0; 

    for(int i = 0; i < SIZE; i++)
    {
        deviationSum1 += pow((arr[i].exam1 - average1), 2); 
        deviationSum2 += pow((arr[i].exam2 - average2), 2); 
        deviationSum3 += pow((arr[i].exam3 - average3), 2); 
        deviationSum4 += pow((arr[i].total - average4), 2);
    }

    std1 = sqrt(deviationSum1 / ((SIZE) - 1)); 
    std2 = sqrt(deviationSum2 / ((SIZE) - 1)); 
    std3 = sqrt(deviationSum3 / ((SIZE) - 1)); 
    std4 = sqrt(deviationSum4 / ((SIZE) - 1)); 

    // Loop average values into an array of size
    for(int index = 0; index < INFO; index++)
    {
        if(index == 0)
            standardDeviation[0] = std1; 
        else if(index == 1)
            standardDeviation[1] = std2; 
        else if(index == 2)
            standardDeviation[2] = std3; 
        else if(index == 3)
            standardDeviation[3] = std4; 
        else 
            cout << "Fail!" << endl; 
    }
}



    cout << "\n"; 
}

/**
* Pre-condition: 
* Post-condition: 
*/
void sort(StudentData arr[])
{
    StudentData temp; 

    for (int i = 0; i < (SIZE - 1); i++)
    {
        for (int j = i + 1; j < SIZE; j++)
        {
            if (arr[i].last_name > arr[j].last_name)
            {
                temp = arr[i];    
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
}
Antworten
8
Es scheint, dass die Funktion print (StudentData [], int [], int [], double [], double []) fehlt. Abishek Shankar vor 3 Jahren 0

1 Antwort auf die Frage

9
Edward

Ich habe eine Reihe von Dingen gefunden, die Ihnen helfen könnten, Ihren Code zu verbessern.

Nicht missbrauchen using namespace std

Putting using namespace stdan der Spitze eines jeden Programms ist eine schlechte Gewohnheit, die Sie gut tun würde, zu vermeiden. Wissen, wann und wann nicht (wie beim Schreiben von Kopfzeilen).

Vermeiden Sie die Verwendung von globalen Variablen

Ich sehe das SIZEund werde INFOals globale Variable und nicht als lokale Variable deklariert. Im Allgemeinen ist es besser, die von Ihrer Funktion benötigten Variablen explizit zu übergeben, anstatt die vage implizite Verknüpfung einer globalen Variablen zu verwenden. Zum Beispiel calcLowesterhält the das StudentDataArray als einen übergebenen Parameter - die Größe dieses Arrays sollte ebenfalls übergeben werden.

Verwenden Sie aussagekräftigere Variablennamen

Die Variablennamen SIZEund INFOsind nicht so beschreibend, wie sie sein könnten. Größe von was? Welche info

Nicht verwenden system("PAUSE")

Es gibt zwei Gründe, um system("cls")oder nicht zu verwenden system("PAUSE"). Die erste ist, dass es nicht für andere Betriebssysteme portierbar ist, die Ihnen jetzt vielleicht egal sind. Die zweite ist, dass es sich um eine Sicherheitslücke handelt, um die Sie sich unbedingt kümmern müssen . Wenn ein Programm definiert und benannt wird PAUSEoder pause, wird dieses Programm das Programm ausführen, anstatt das, was Sie beabsichtigen, und das andere Programm könnte alles sein. Isolieren Sie diese zunächst in separate Funktionen pause()und ändern Sie dann Ihren Code, um diese Funktionen anstelle von aufzurufen system. Schreiben Sie anschließend den Inhalt dieser Funktionen neu, um mit C ++ das zu tun, was Sie möchten. Zum Beispiel:

void pause() {
    getchar();
}

Allgemeine Portabilität

Dieser Code könnte gemacht tragbar sein, wenn zusätzlich zu den Änderungen in dem vorigen Punkt, lassen Sie die Windows-only - Dateien enthalten #include "stdafx.h".

Arrays den seriell nummerierten Variablen vorziehen

Der Code verfügt derzeit über eine große Anzahl von Variablen, die fortlaufend nummeriert sind, wie z. B. std1, std2usw. Dies ist ein deutlicher Hinweis darauf, dass Sie ein Array besser verwenden könnten. Der Code kann dann kompakter, effizienter und einfacher zu warten sein. Überlegen Sie sich beispielsweise, wie viel Code Sie ändern müssten, wenn 4 Prüfungen statt 3 wären.

Betrachten Sie die Effizienz

Anstatt einen Durchlauf durch die Daten durchzuführen, um den niedrigsten Wert zu ermitteln, und dann einen anderen, um den höchsten Wert zu finden, warum sollten sie nicht beide gleichzeitig mit einem einzigen Durchlauf durch die Daten erhalten? Tatsächlich können alle Ihre Statistiken mit einem einzigen Durchlauf durch die Daten berechnet werden.

Verwenden Sie constwo sinnvoll

Die meisten Routinen in diesem Code beziehen sich auf Daten, die nicht geändert werden. Für ein naheliegendes Beispiel verwendet die printRoutine fünf verschiedene Arrays als Argumente, ändert jedoch keines davon. Sie können dies deutlich machen, indem Sie constdie Parameter deklarieren.

Verwenden Sie bessere Routinenamen

Die Funktion getTotalscheint überhaupt nichts zu bekommen. Tatsächlich berechnet man die Gesamtpunktzahl des Schülers. Ein besserer Name könnte sein calculatTotal. Es wäre auch sinnvoll, die Summe für nur einen Schülerrekord berechnen zu lassen. Ich würde es so schreiben:

int calculateTotal(const StudentData& student)
    return student.exam1 + student.exam2 + student.exam3; 
}

Geben Sie aus den Unterprogrammen etwas Nützliches zurück

Jede einzelne Routine wird als zurückgegeben deklariert void. Da stimmt etwas nicht. Zum Beispiel gibt die calculateTotaloben erwähnte Routine die Summe zurück. Sie würden es dann in einer Schleife außerhalb der Routine verwenden:

for(int i = 0; i < NUM_STUDENTS; ++i) {
    students[i].total = calculateTotal(students[i]);
}

Der Vorteil ist, dass Sie jetzt eine einzige Schleife erstellen und sowohl die Noten als auch die Summen gleichzeitig aktualisieren können.

Übergeben Sie immer eine Größe, wenn Sie einen Zeiger an ein Array übergeben

Wie bereits erwähnt, sollten Sie beim Übergeben StudentDatades Arrays auch die Größe des Arrays übergeben. Im Allgemeinen sollten Sie sich daran gewöhnen, dies für jedes übergebene Array zu tun .

Dateinamen nicht hardcode

Im Allgemeinen ist es keine gute Idee, einen Dateinamen in Software fest zu codieren, und im Allgemeinen besonders schlecht, wenn es sich um einen absoluten Dateinamen handelt (im Gegensatz zu einem Dateinamen mit einem relativen Pfad). Stattdessen ist es besser, dem Benutzer des Programms zu erlauben, den Namen wie bei einem Befehlszeilenparameter anzugeben.

Seien Sie flexibler mit Daten

Das Programm verlangt derzeit, dass die Eingabedatei genau neun Schülerdatensätze enthält. Das ist nicht besonders flexibel. Stattdessen wäre es für den Benutzer schön, wenn eine beliebige Anzahl von Studenten vorhanden sein könnte. Bemühen Sie sich, diese Flexibilität in Ihrer Software bereitzustellen. Beispielsweise könnte Ihr Programm Studentendateien einlesen, bis entweder das Ende der Eingabedatei oder ein Fehler in den Eingabedaten auftritt.

Fügen Sie die Fehlerprüfung hinzu

Die Dateneingabe erfordert in der Regel eine sorgfältige Prüfung der meisten Software. Das Prüfen auf fehlerhafte Eingaben und deren sorgfältige Behandlung erfordert häufig einen erheblichen Nachwuchs, Zeit und Code. Möglicherweise sollten Sie die Eingabefunktion in einer separaten Routine isolieren und Fehlermeldungen bereitstellen, die dem Benutzer helfen können, Probleme zu identifizieren und zu beheben. Wenn zum Beispiel die Eingabedatei nicht gefunden wird, versucht das Programm trotzdem, fortzufahren. Das kann doch nicht richtig sein!

Erwägen Sie die Verwendung von Standardroutinen

C ++ bietet eine Vielzahl nützlicher Funktionen std::sort, die Sie anstelle Ihrer eigenen handgeschriebenen sortFunktion verwenden könnten . Selbst wenn die aktuelle Aufgabe ihre Verwendung nicht zulässt, ist es äußerst nützlich, sie zu kennen und sie vorrangig für das Schreiben eigener Aufgaben zu verwenden. Sie sind fast immer schneller und weniger fehleranfällig, und durch die Verwendung von Bibliothekssoftware können Sie Ihren eigenen Code schneller und genauer entwickeln.

Auslassen return 0

Wenn ein C ++ - Programm das Ende des mainCompilers erreicht, wird automatisch Code generiert, der 0 zurückgibt. Es besteht also kein Grund, return 0;explizit am Ende von main.

Eliminieren Sie nicht verwendete Variablen

Nicht verwendete Variablen sind ein Zeichen für schlechte Codequalität. Daher sollte deren Beseitigung Vorrang haben. In diesem Code werden calcLowestSets smallestund calcHighestSets verwendet, biggestaber keine dieser Variablen wird tatsächlich verwendet. Mein Compiler sagt mir das auch. Ihr Compiler ist wahrscheinlich auch klug genug, Ihnen dies zu sagen, wenn Sie ihn darum bitten.

Objektorientierung verwenden

Da Sie in C ++ schreiben, ist es sinnvoll, über Methoden zu verfügen, die mit einer Klasse arbeiten, z. B. StudentDataMember-Funktionen und keine separaten Funktionen. Sie haben vielleicht noch nichts über Objekte oder Klassen gelernt, aber es ist eine der Hauptstärken von C ++ und etwas, das Sie bald lernen sollten, falls Sie dies nicht bereits getan haben. Verwenden Sie Objekte, wo sie Sinn machen.

Ich bin persönlich dagegen, eine Rückkehr von der Hauptperson wegzulassen. Es ist eine syntaktische Anomalie. Reinderien vor 2 Jahren 0
Außerdem ist stdafx nicht Windows-spezifisch, sondern MSVC-spezifisch. Mit anderen Worten, es würde sich nicht auf Bloodshed kompilieren. Reinderien vor 2 Jahren 0
Blutvergießen? Wer verwendet einen 13 Jahre alten Compiler? GCC ist wahrscheinlich ein besseres Beispiel für das OP eines anderen Compilers, auf den er zielen möchte. The6P4C vor einem Jahr 0