Thread: Records(structs) pgrm help.

  1. #1
    Registered User
    Join Date
    Jul 2015
    Posts
    5

    Records(structs) pgrm help.

    Write a program that reads a student's name followed by their test score. The program should output each students name followed by the test scores and the relevant grade. It should also find and print the highest test score and the name of the students having the highest test score.

    Student data should be stored in a struct variable of type studentType, which has four components: studentFName and studentLName of type string, testscore of type int (testscore is between 0 and 100), and grade of type char. Suppose that the class has 20 students. Use an array of 20 components of type studentType.

    The program must contain at least the following functions:

    a.) a function to read the students data into the array.'
    b.) a function to assign the relevant grade to each student.
    c.) a function to find the highest test score.
    d.) a function to print the names of the students having the highest test score.

    The program must output each students name in this form: last name followed by a comma, followed by a space, followed by the 1st name, and the name must be left-justified. Moreover, other than declaring the variables and opening the input and output files, the function main should only be a collection of functions calls.


    I am really stuck on this and would like some help. I have a mac and am using codeblocks. My issue is that it compiles, but it keeps stopping at finding the data file.

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <iomanip>
    
    
    using namespace std;
    
    
    const int NO_OF_STUDENTS = 20;
    
    
    struct studentType
    {
        string studentFName;
        string studentLName;
        int testScore;
        char grade;
    };
    
    
    void getData(ifstream& inData, studentType sList[], int listSize);
    void calculateGrade(studentType sList[], int listSize);
    int highestScore(const studentType sList[], int listSize);
    void printResult(ofstream& outData, const studentType sList[], int listSize);
    
    
    int main()
    {
        ifstream inData;
        ofstream outData;
        studentType studentList[NO_OF_STUDENTS];
        inData.open("Data.txt");
        if (!inData)
        {
            cout << "The input file does not exist."
                << endl;
            system("PAUSE");
            return 1;
        }
    
    
        outData.open("DataOut.txt");
        if (!outData)
        {
            cout << "Could not open the output file."
                << endl;
            system("PAUSE");
            return 1;
        }
    
    
        getData(inData, studentList, NO_OF_STUDENTS);
        calculateGrade(studentList, NO_OF_STUDENTS);
        printResult(outData, studentList, NO_OF_STUDENTS);
        system("PAUSE");
        return 0;
    }
    
    
    void getData(ifstream& inFile, studentType sList[], int listSize)
    {
        for (int i = 0; i < listSize; i++)
            inFile >> sList[i].studentFName >> sList[i].studentLName
            >> sList[i].testScore;
    }
    
    
    void calculateGrade(studentType sList[], int listSize)
    {
        int score;
        for (int i = 0; i < listSize; i++)
            if (score >= 90)
                sList[i].grade = 'A';
            else if (score >= 80)
                sList[i].grade = 'B';
            else if (score >= 70)
                sList[i].grade = 'C';
            else if (score >= 60)
                sList[i].grade = 'D';
            else
                sList[i].grade = 'F';
    
    
    }
    
    
    int highestScore(const studentType sList[], int listSize)
    {
        int score[100];
        int highscore = score[0];
        for (int i = 0; i < listSize; i++)
        {
    
    
            if (score[i] > highscore)
            {
                highscore = score[i];
            }
    
    
        }
    
    
    }
        void printResult(ofstream& outFile, const studentType sList[], int listSize)
        {
            int maxScore = highestScore(sList, listSize);
            int i;
            outFile << setw(15) << "Student Name" << setw(10) << "Test Score" << setw(7) << "Grade" << endl;
            for (i = 1; i < listSize; i++)
            outFile << left << setw(25) << sList[i].studentLName + ", " + sList[i].studentFName<< right << " " << setw(5) << sList[i].testScore<< setw(6) << " " << sList[i].grade << endl;
            outFile << endl << "The higest test score is: " << maxScore << endl;
            outFile << "Students the have the higest test scores are:" << endl;
            for (i = 1; i < listSize; i++)
                if (sList[i].testScore == maxScore)
                    outFile << sList[i].studentLName + ", " + sList[i].studentFName << endl;
        }
    main.cppData.txt

    You just need to create DataOut.txt file because for some reason I cannot upload/attach the empty file.

    Thank you.

  2. #2
    Guest
    Guest
    I take it your program prints "The input file does not exist." and then terminates, correct?

    If so, then you need to make absolutely sure Data.txt exists in the same directory as your executable. It's so common to get this wrong, happened to me on many occasions.

    A few more things, while we're at it:

    Declare NO_OF_STUDENTS inside main, not before. You can declare it constexpr (instead of const) if you want, since its value is known at compile time.

    Code:
    void calculateGrade(studentType sList[], int listSize)
    {
        int score; // where does score acquire a value?
        for (int i = 0; i < listSize; i++)
            if (score >= 90) // it will be 'undefined' here, for instance
                sList[i].grade = 'A';
            else if (score >= 80)
                sList[i].grade = 'B';
            else if (score >= 70)
                sList[i].grade = 'C';
            else if (score >= 60)
                sList[i].grade = 'D';
            else
                sList[i].grade = 'F';
    }
    highestScore promises to return an int, but doesn't. It also has an odd design I'd say. Since within that function, you cycle through all scores, you just need to keep track of the highest value encountered so far. So a simple int will do; no arrays are needed. If you also need the index of the highest scoring student in the sList array, then that's just another integer updated whenever your loop encounters a new highscore (= new highscorer). Since you want to get that information out of the function, you could pass "highscore" and "studentIndex" variables to the function by reference, instead of returning a (single) value. Otherwise you would have to create a struct (or std::pair) holding both values and return that.

    Make sure you compile frequently and with warnings activated. That's very important when learning.

    p.s. Isn't Apple XCode free? I haven't tried it, but I suspect that on a Mac, it's preferrable to CodeBlocks.
    Last edited by Guest; 07-15-2015 at 05:21 PM.

  3. #3
    Registered User
    Join Date
    Jul 2015
    Posts
    5
    Also I am not familiar with constexpr.
    "
    So a simple int will do; no arrays are needed. If you also need the index of the highest scoring student in the sList array, then that's just another integer updated whenever your loop encounters a new highscore (= new highscorer). Since you want to get that information out of the function, you could pass "highscore" and "studentIndex" variables to the function by reference, instead of returning a (single) value."

    I am not understanding the another integer part you mentioned above. I understand the loop. Sorry its been a while since I used c++.
    I put the NO_OF_STUDENTS inside main. Thank you for that.
    Last edited by y_p28; 07-15-2015 at 05:39 PM.

  4. #4
    Guest
    Guest
    Yes, like so:
    Code:
    int main()
    {
        constexpr int NO_OF_STUDENTS = 20;
    }
    It's usually bad practice to declare variables globally (i.e. outside of main).

    As for constexpr, it's like const but for values known at compile time:
    Code:
    void fn(int value)
    {
        constexpr int testRuns = 15; // testRuns is always 15, it's hard-coded
    
        const int valueTwice = value * 2; // valueTwice won't change after being declared, but value might be computed at runtime
    }

  5. #5
    Registered User
    Join Date
    Jul 2015
    Posts
    5
    Oh ok that makes sense.
    As for the highest score, I am not understanding the idea of what you are saying.
    I downloaded the Xcode 7 beta and its giving me trouble, so going to try Xcode 6.4
    The current error I am receiving is just warnings on codeblocks. I put the textiles in the main.cpp directory, but its still not doing anything.

    Here is the warning I am getting
    ++ -Wall -fexceptions -g -c /Users/yashpatel/Documents/YPatelLab1/main.cpp -o obj/Debug/main.o
    /Users/yashpatel/Documents/YPatelLab1/main.cpp:64:7: warning: variable 'score' is uninitialized when used here [-Wuninitialized]
    if (score >= 90)
    ^~~~~
    /Users/yashpatel/Documents/YPatelLab1/main.cpp:62:11: note: initialize the variable 'score' to silence this warning
    int score;
    ^
    = 0
    /Users/yashpatel/Documents/YPatelLab1/main.cpp:91:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^
    2 warnings generated.
    g++ -o bin/Debug/YPatelLab1 obj/Debug/main.o
    Output file is bin/Debug/YPatelLab1 with size 63.52 KB
    Process terminated with status 0 (0 minute(s), 2 second(s))
    0 error(s), 2 warning(s) (0 minute(s), 2 second(s))

  6. #6
    Guest
    Guest
    Yes, these are problems I alluded to in my first reply. Inside calculateGrade() you declare an integer score, but you give it no value. Afterwards you do try to use this undefined value in comparisons (if (??? >= 90)) - that's why the compiler complains.

    Regarding the highest score: Imagine all students (and their scores) arriving on a conveyor belt. You're standing there taking notes about the passer-bys. Now instead of writing down every student and score, imagine writing down the highest score you've encountered so far. If a student with a higher score passes you on the belt, you erase the old highscore and scribble in the new one (along with the name of that student). This means you have 1 variable to keep track of the highscore and 1 variable to keep track of the student. The for-loop is the conveyor belt, the score is sList[i].score and the student belonging to that score is sList[i].
    Last edited by Guest; 07-15-2015 at 06:25 PM.

  7. #7
    Registered User
    Join Date
    Jul 2015
    Posts
    5
    Yes but what if more than one person has the same score? If lets say 3-4 students have 100%. So do I remove that integer?

  8. #8
    Guest
    Guest
    Oh right, I hadn't even looked at the printResult function. To allow for multiple high scorers, some sort of array is needed of course; disregard my advice in that case. Assuming you haven't learned about containers like std::vector yet, you will have to create an array (or two) outside of your highestScore function and then pass these as arguments (to be modified).

  9. #9
    Registered User
    Join Date
    Jul 2015
    Posts
    5
    Ok so Xcode is working better than code blocks.
    Here is what I am getting.

    Data.txt:
    Clark Kent 100
    Bruce Wayne 100
    Barry Allen 100
    Diana Prince 90
    Kara Kent 92
    Hal Jordan 98
    Billy Batson 96
    Arthur Curry 38
    John Jones 24
    Oliver Queen 52
    Carter Hall 22
    Shiera Hall 72
    Zatanna Zatara 82
    Ray Palmer 62
    Michael Carter 68
    Kent Nelson 46
    Nathaniel Adam 88
    Karen Starr 78
    Terry Mcginnis 42
    Dick Grayson 56

    Student NameTest Score Grade
    Wayne, Bruce 100 A
    Allen, Barry 100 A
    Prince, Diana 90 A
    Kent, Kara 92 A
    Jordan, Hal 98 A
    Batson, Billy 96 A
    Curry, Arthur 38 A
    Jones, John 24 A
    Queen, Oliver 52 A
    Hall, Carter 22 A
    Hall, Shiera 72 A
    Zatara, Zatanna 82 A
    Palmer, Ray 62 A
    Carter, Michael 68 A
    Nelson, Kent 46 A
    Adam, Nathaniel 88 A
    Starr, Karen 78 A
    Mcginnis, Terry 42 A
    Grayson, Dick 56 A


    The higest test score is: 0
    Students the have the higest test scores are:

    I am really stuck, if you could show me that would be really helpful. I know I am almost there, but still getting errors. Clark Kent disappears from the list, its not giving the highest score and names, also everyone is getting an A.

  10. #10
    Guest
    Guest
    I wanted to guide you to the solution, but I guess it's time to show it directly:
    Code:
    void calculateGrades(studentType sList[], int listSize)
    {
        int score;
        for (int i = 0; i < listSize; i++)
            score = sList[i].testScore; // <- you were missing this. 'score' never acquired a value to compare with others
            if (score >= 90)
                sList[i].grade = 'A';
            else if (score >= 80)
                sList[i].grade = 'B';
            else if (score >= 70)
                sList[i].grade = 'C';
            else if (score >= 60)
                sList[i].grade = 'D';
            else
                sList[i].grade = 'F';
    }
    Note that I've made the function name plural. It calculates grades and the name should reflect that.

    Regarding your highestScore function (should be Scores too, as you work with more than one), what is your rationale behind it? In other words, how would you describe in written words what it does to arrive at a result? This is probably something your tutor wants you to work out. The coding part I can help you with, but the logic part is on you, or I'd be doing your homework

    In your current approach, one immediate problem is that you have an uninitialised array score[100] that you're trying to do work with. What do you think the value of score[0] on line 4 is?
    Code:
    int highestScore(const studentType sList[], int listSize)
    {
        int score[100];
        int highscore = score[0];
        for (int i = 0; i < listSize; i++)
        {
            if (score[i] > highscore)
            {
                highscore = score[i];
            }
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 01-08-2013, 07:55 AM
  2. Typedef Structs inside Typdef structs
    By gremory in forum C Programming
    Replies: 21
    Last Post: 12-30-2011, 07:48 PM
  3. [ noob question ] Help with structs within structs
    By Riverfoot in forum C Programming
    Replies: 3
    Last Post: 04-26-2011, 07:24 PM
  4. passing structs & pointers to structs as arguments
    By Markallen85 in forum C Programming
    Replies: 6
    Last Post: 03-16-2004, 07:14 PM
  5. Files&Records(Entering records)
    By Beginnerinc in forum C Programming
    Replies: 1
    Last Post: 01-29-2003, 09:11 AM

Tags for this Thread