0

I'm trying to write a program that has a user input student names, their ages, their GPAs, and their graduations dates (i.e. 'F13', F for Fall, S for Spring, then the last two digits of the year). This information goes into a linked list, then the user can search a name or part of a name to find students and display their information.

#include <iostream>
#include <cstring>
using namespace std;

const char NAME_SIZE = 50;

struct StudentInfo
{
   char studentName[NAME_SIZE];
   int age;
   double gpa;
   char graduationSemester[4];
   StudentInfo *next;
};

void displayStudentNames(StudentInfo *top);
void displayStudentInfo(StudentInfo *top);

int main(){
    StudentInfo *top = 0;
    cout << "Please enter the students. Enter the name, age, gpa, and semester of graduation (e.g. F13)." << endl;
    cout << "Enter an empty name to stop." << endl << endl;
    bool done = false;
    while(!done){
        char graduationBuffer[4];
        char nameBuffer[NAME_SIZE];
        cin.getline(nameBuffer, NAME_SIZE);
        if(nameBuffer[0] != 0){
            //create new struct in list
            StudentInfo *temp = new StudentInfo;
            strcpy(temp->studentName, nameBuffer);
            //do-while loop for age input & validation
            do{
                cin >> temp->age;
                if(temp->age < 1 || temp->age > 120){
                    cout << "Please choose an age between 1 and 120." << endl;
                }
            }while(temp->age < 1 || temp->age > 120);
            //do-while loop for gpa input & validation
            do{
                cin >> temp->gpa;
                if(temp->gpa < 0 || temp->gpa > 4){
                    cout << "Please choose a gpa between 0 and 4." << endl;
                }
            }while(temp->gpa < 0 || temp->gpa > 4);
                cin.getline(graduationBuffer, 4);
                strcpy(temp->graduationSemester, graduationBuffer);
            cin.ignore(80, '\n');
            temp->next = top;
            top = temp;
        //else statement occurs when user input is ended by empty name
        }else{
            //function is called to display all input names
            displayStudentNames(top);
            //function is called to ask for name to search for
            displayStudentInfo(top);
            //after functions are called, boolean set to true to end the program
            done = true;
        }
    }
}

//function to display the names of students in the linked list
void displayStudentNames(StudentInfo *top){
    cout << "Here are the students that you entered: " << endl << endl;
    while(top){
        cout << top->studentName << endl;
        top = top->next;
    }
    cout << endl;
}

//function to search for student and display info
void displayStudentInfo(StudentInfo *top){
    char name[NAME_SIZE];
    StudentInfo *node = top;
    bool done = false;
    while(!done){
        cout << "Which student do you want? ";
        cin.getline(name, NAME_SIZE);
        if(name[0] != 0){
            do{
                const char *str = top->studentName;
                const char *substr = name;
                const char *index = str;
                if(node->studentName == strstr(node->studentName,name)){
                    cout << "Name: " << top->studentName;
                    cout << ", Age: " << top->age;
                    cout << ", GPA: " << top->gpa;
                    cout << ", Graduation Date: " << top->graduationSemester;
                    cout << endl << endl;
                }
                node = node->next;
            }while(node != NULL);
        }else{
            cout << "No students found." << "Goodbye!" << endl;
            done = true;
        }
    }
}

I am having a few problems, however. 1) when I use the displayStudentNames function, the names are being printed in reverse order from what I put in, 2) graduation dates aren't being printed out, so I'm not sure if they're being stored correctly, if at all, 3) when I use the displayStudentInfo function, it either works incorrectly, or crashes the program.

Edited by Emily_2: cleaner code

2
Contributors
2
Replies
15
Views
1 Year
Discussion Span
Last Post by David W
0

Why are you using C strings in a C++ program ? (Way better to use C++ string, most of the time.)

0

...1) when I use the displayStudentNames function, the names are being printed in reverse order from what I put in,

Because you are using a 'push_front' with each new student you add.
You could easily use a 'push_back' instead
(and keep a pointer to the 'back' so you can easily add the next student after the 'back'.)

2) graduation dates aren't being printed out, so I'm not sure if they're being stored correctly, if at all, 3) when I use the displayStudentInfo function, it either works incorrectly, or crashes the program.

You are not re-setting the 'top' pointer at the start of each new loop query

If you really must store C strings in your stuct ...
see this edit that uses C++ strings to ease your take in of strings ...
(You can easily store the data there as a C string ... And it's easy to chop off any char's that exceed the max length that you wish to store.)

// Student.cpp //

#include <iostream>
#include <cstring>
#include <string> // to handle input of string of any size //

using namespace std;


const int NAME_SIZE = 49;

struct Student
{
   char name[NAME_SIZE+1];
   int age;
   double gpa;
   char gradSemesterAndYear[4];
   Student *next;
};


void displayStudentNames( const Student* top );
void displayStudentInfo( const Student* top );



int main()
{
    string line;
    Student *top = 0;

    cout << "You will be prompted to enter: \n"
         << "name, \n"
         << "age, \n"
         << "gpa, \n"
         << "semester of graduation (e.g. F13) \n"
         << "\nPlease note! \n"
         << "To quit this student data take in loop, enter an empty line for the name.\n\n";

    bool done = false;
    while( !done )
    {
        cout << "Enter name (or enter an empty line to exit): " << flush;
        getline( cin, line );
        if( line.size() )
        {
            //create new struct in list
            Student* temp = new Student;
            int len = line.size();
            if( len < NAME_SIZE )
            {
                strncpy( temp->name, &line[0], len );
                temp->name[len] = 0;
            }
            else
            {
                strncpy( temp->name, &line[0], NAME_SIZE );
                temp->name[NAME_SIZE] = 0;
            }

            // loop for age input & validation
            for( ; ; )
            {
                cout << "Enter age (1..120): " << flush;
                if( cin >> temp->age && cin.get()== '\n' )
                {
                    if( temp->age >= 1 && temp->age <= 120 ) break;
                    //else
                    cout << "ERROR ... expecting an age between 1 and 120 \n";
                }
                else
                {
                    cin.clear();
                    cin.sync();
                    cout << "ERROR ... expecting a number \n";
                }
            }
            // loop for gpa input & validation
            for( ; ; )
            {
                cout << "Enter gpa (0..4): " << flush;
                if( cin >> temp->gpa && cin.get() == '\n' )
                {
                    if( temp->gpa >= 0 && temp->gpa <= 4 ) break;
                    // else
                    cout << "ERROR ... Valid range of gpa is 0..4 \n";
                }
                else
                {
                    cin.clear();
                    cin.sync();
                    cout << "ERROR ... expecting a number \n";
                }
            }

            for( ; ; )
            {
                cout << "Enter semester and year to graduate "
                     << "(for example, enter S13): " << flush;
                getline(cin, line);
                len = line.size();
                if( len == 3 ) break; // could add more validation //
                // else
                cout << "ERROR ... expecting exactly 3 char's of data \n";
            }


            strncpy(temp->gradSemesterAndYear, &line[0], 3 );
            temp->gradSemesterAndYear[3] = 0;

            // push_front ...
            temp->next = top;
            top = temp;
            cout << endl;

        }
        else //else statement occurs when user input is ended by empty name
        {
            //function is called to display all input names
            displayStudentNames(top);
            //function is called to ask for name to search for
            displayStudentInfo(top);
            //after functions are called, boolean set to true to end the program
            done = true;
        }
    }
}

//function to display the names of students in the linked list
void displayStudentNames( const Student* top )
{
    cout << "Here are the students that you entered: \n\n";
    while( top )
    {
        cout << top->name << endl;
        top = top->next;
    }
    cout << endl;
}

//function to search for student and display info
void displayStudentInfo( const Student* top )
{
    string line;
    char name[NAME_SIZE+1];
    bool done = false;
    while( !done )
    {
        cout << "Which student do you want (or enter a blank line to exit) ? " << flush;
        getline( cin, line);
        if( line.size() )
        {
            int len = line.size();
            if( len > NAME_SIZE ) len = NAME_SIZE;
            strncpy( name, &line[0], len );
            name[len] = 0;

            const Student* node = top; // set top at start of each query //

            do
            {
                //const char *str = top->name;
                //const char *substr = name;
                //const char *index = str;
                if(node->name == strstr(node->name, name))
                {
                    cout << "Name: " << top->name;
                    cout << ", Age: " << top->age;
                    cout << ", GPA: " << top->gpa;
                    cout << ", Graduation Date: " << top->gradSemesterAndYear;
                    cout << endl << endl;
                }
                node = node->next;
            }
            while( node != 0 );
        }
        else
        {
            cout << "You entered a blank line to signal to quit ... Goodbye!\n";
            done = true;
        }
    }
}

Edited by David W

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.