these one code, from line [63-71] of the original code

// for adding more students
        cout << endl << "Want to add more student?(yes/no): ";
        string add_student;
        cin >> add_student;

        if(add_student == "yes")
        {
            student_counter = 0;
        }

the program seems "doesn't detect" the cin code above, it just go through without waiting for any input. can anyone explain anything from this event?

this is the original code...

#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::setprecision;
using std::streamsize;
using std::string;
using std::vector;

int main()
{

    // delaring needed variable; for main scope to keep the value until end program.
    vector<string> student_name;
    vector<double> overall_grade;

    // main device; input name and grade into variable.
    for (unsigned int student_counter = 1; student_counter == 1; ++student_counter)
    {
        cout << "Insert student\'s name: ";
        string name_input;

        while (cin >> name_input)
        {
            student_name.push_back(name_input);

            // collecting grade data
            cout << endl << "Insert his/her midterm\'s grade: ";
            double midterm_grade;
            cin >> midterm_grade;

            cout << "Insert his/her final\'s grade: ";
            double final_grade;
            cin >> final_grade;

            int num_counter = 0;
            double homework_sum = 0;
            double homework_input;

            cout << "Insert his/her homework's grade: ";
            while (cin >> homework_input)
            {
                ++num_counter;
                homework_sum = homework_sum + homework_input;
            }

            double homework_average = homework_sum / num_counter;

            // combining data.
            double grade_sum = (0.2*midterm_grade + 0.4*final_grade + 0.4*homework_average);

            // classify the combined data.
            overall_grade.push_back(grade_sum);
        }

        // for adding more students
        cout << endl << "Want to add more student?(yes/no): ";
        string add_student;
        cin >> add_student;

        if(add_student == "yes")
        {
            student_counter = 0;
        }
    }

    // define a type for listing element in integer.
    typedef vector<double>::size_type ele_num;

    // define a variable to define amount of element in the set.
    ele_num ele_name_size = student_name.size();
    ele_num ele_grade_size = overall_grade.size();

    // detecting input (name and grade)
    if (ele_name_size == 0)
    {
        cout << endl << "You are not inserting any student\'s name, try again.";
        return 1;
    }

    if(ele_grade_size == 0)
    {
        cout << endl << "You are not inserting any grade data of student, try again.";
        return 1;
    }

    // accessing the data stored.
    for (unsigned int list_counter = 0; list_counter < ele_name_size && list_counter < ele_grade_size; ++list_counter)
    {
        // writing the data
        streamsize prec = cout.precision();
        cout << endl  << endl << endl << student_name[list_counter] <<
                "\'s overall grade: " << setprecision(3) <<
                overall_grade[list_counter] << setprecision(prec) << endl;
    }

    return 0;
}

thnx 4 reading, hope anyone can give a hand.

Recommended Answers

All 14 Replies

When you enter numbers (like your doubles) the ENTER is left in the input buffer, since it's not a number. You need to clear it before reading a string or a character. Look into the cin.ignore method.

1- until now, where at accelerated C++ chpter 4, there no cin.ignore(), yet.

2- still trying the method(based on google) and this is it, but it not works, like nothing changes from before.

3- anyway thnx 4 reply

edit :-

4- not really understood what you are trying to say...

#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::setprecision;
using std::streamsize;
using std::string;
using std::vector;

int main()
{

    // delaring needed variable; for main scope to keep the value until end program.
    vector<string> student_name;
    vector<double> overall_grade;

    // main device; input name and grade into variable.
    for (unsigned int student_counter = 1; student_counter == 1; ++student_counter)
    {
        cout << "Insert student\'s name: ";
        string name_input;

        while (cin >> name_input)
        {
            student_name.push_back(name_input);
            cin.ignore();

            // collecting grade data
            cout << endl << "Insert his/her midterm\'s grade: ";
            double midterm_grade;
            cin >> midterm_grade;
            cin.ignore();

            cout << "Insert his/her final\'s grade: ";
            double final_grade;
            cin >> final_grade;
            cin.ignore();

            int num_counter = 0;
            double homework_sum = 0;
            double homework_input;

            cout << "Insert his/her homework's grade: ";
            while (cin >> homework_input)
            {
                ++num_counter;
                homework_sum = homework_sum + homework_input;
                cin.ignore();
            }

            double homework_average = homework_sum / num_counter;

            // combining data.
            double grade_sum = (0.2*midterm_grade + 0.4*final_grade + 0.4*homework_average);

            // classify the combined data.
            overall_grade.push_back(grade_sum);
        }

        // for adding more students
        cout << endl << "Want to add more student?(yes/no): ";
        string add_student;
        cin >> add_student;
        cin.ignore();

        if(add_student == "yes")
        {
            student_counter = 0;
        }
    }

    // define a type for listing element in integer.
    typedef vector<double>::size_type ele_num;

    // define a variable to define amount of element in the set.
    ele_num ele_name_size = student_name.size();
    ele_num ele_grade_size = overall_grade.size();

    // detecting input (name and grade)
    if (ele_name_size == 0)
    {
        cout << endl << "You are not inserting any student\'s name, try again.";
        return 1;
    }

    if(ele_grade_size == 0)
    {
        cout << endl << "You are not inserting any grade data of student, try again.";
        return 1;
    }

    // accessing the data stored.
    for (unsigned int list_counter = 0; list_counter < ele_name_size && list_counter < ele_grade_size; ++list_counter)
    {
        // writing the data
        streamsize prec = cout.precision();
        cout << endl  << endl << endl << student_name[list_counter] <<
                "\'s overall grade: " << setprecision(3) <<
                overall_grade[list_counter] << setprecision(prec) << endl;
    }

    return 0;
}

Then try reading the string twice. Once to clear the buffer, Again to actually read the input.

still not working... :(

btw, I re-read something, becoz I remember reading this somewhere in the book before, from chapter 1, thnx 4 your information about the cin.ignore, I understand a little about a 'hidden' concept of cin(talking about the flush and buffer)

The input operation has another side effect: It causes our prompt, which asks for the user's name, to appear on the computer's output device. In general, the input-output library saves its output in an internal data structure called a buffer, which it uses to optimize output operations. Most systems take a significant amount of time to write characters to an output device, regardless of how many characters there are to write. To avoid the overhead of writing in response to each output request, the library uses the buffer to accumulate the characters to be written, and flushes the buffer, by writing its contents to the output device, only when necessary. By doing so, it can combine several output operations into a single write.

There are three events that cause the system to flush the buffer. First, the buffer might be full, in which case the library will flush it automatically. Second, the library might be asked to read from the standard input stream. In that case, the library immediately flushes the output buffer without waiting for the buffer to become full. The third occasion for flushing the buffer is when we explicitly say to do so.

Hi Vastor,
Please use the getline function instead of cin. The syntax for it is,

getline (cin,str);

. So, borrowing from your program, I'd write

//Add more students
        cout << endl << "Want to add more student?(yes/no): ";
        string add_student;
        //use this
        getline (cin,add_student); 
        //instead of this: cin >> add_student;

Hi Vastor,
Please use the getline function instead of cin. The syntax for it is,

getline (cin,str);

. So, borrowing from your program, I'd write

//Add more students
        cout << endl << "Want to add more student?(yes/no): ";
        string add_student;
        //use this
        getline (cin,add_student); 
        //instead of this: cin >> add_student;

thnx 4 reply, still, not working, I'm using Code::Blocks if compiler's problem is the case.

btw, I hope I can use functionality that I already learn, well, it is not much of problem as we have Google ;P

anyway, I hope anyone can give a hand in solving this problem too..

Hi Vastor,
I might have found the answer to your problem. There is a logical error with your program. It is to do with the two WHILE loops that you have. The conditions they are evaluating will never be false and thus, once we get into the loop, we never come out. What I have done is add a break statement to both of them. The program executes and runs okay now. Please see the changes I've made;

while (cin >> name_input)
        {
            student_name.push_back(name_input);

            // collecting grade data
            cout << endl << "Insert his/her midterm\'s grade: ";
            double midterm_grade;
            cin >> midterm_grade;

            cout << "Insert his/her final\'s grade: ";
            double final_grade;
            cin >> final_grade;

            int num_counter = 0;
            double homework_sum = 0;
            double homework_input;

            cout << "Insert his/her homework's grade: ";
            while (cin >> homework_input)
            {
                ++num_counter;
                homework_sum = homework_sum + homework_input;
                break;//BREAK to exit out of loop
            }
            cout<<"homeworksum is  "<<homework_sum;
            double homework_average = homework_sum / num_counter;

            // combining data.
            double grade_sum = (0.2*midterm_grade + 0.4*final_grade + 0.4*homework_average);

            // classify the combined data.
            overall_grade.push_back(grade_sum);
            break;//BREAK to exit out of loop
        }
commented: What's the sense of having a loop then? -4

ermm, did you see my attachment file in the first post?,

I mean in the console I write end-of-file symbol (something like this "^Z")
it will get me out of loop..

btw, by looking at my code, where I'm using vector and while(cin), obivously it mean to store amount of data that desired by user, as u can see on above code u post, line 26, homework_average, of course that mean I'm expecting amount of data from user more than one, so if we break the loops, the instruction on line 26 become useless...

and if you are missing what the real problem is, I expected result like this :-

Insert student's name: Hakim

Insert his/her midterm's grade: 50
Insert his/her final's grade: 25
Insert his/her homework's grade: 25
50
^Z

Want to add more student?(yes/no): yes

Insert student's name: Hafiz

Insert his/her midterm's grade: 25
Insert his/her final's grade: 50
Insert his/her homework's grade: 50
25
^Z

Want to add more student?(yes/no): no

Hakim's overall grade: 35

Hafiz's overall grade: 40

Process return blablabla....

anyway, thanx for trying to answer ^_^

just use system("pause") in the end before return

commented: Don't ever suggeat system("pause"); again! -4

Vastor, did you test the program with the instructions I had given? Please do. I have attached screenshots from my test. As you'll see, the program works as you want it to, unless there's something I'm missing. I've input the details for three students successfully. And when I answer no during the fourth input, the program prints out the details of the 3 students.

just use system("pause") in the end before return

Search for this terrible function call on this board and learn why we do not suggest it.

yeah, everything work in your given code, except the part where the program asking for homework grade, as you can see, I barely see any teacher that give just ONE homework, that's why I use while cin to work for that, the end input for the program on homework's input will be decide by the user.

like in before post where I insert 50, and 25, then the instruction from line26 will calculate (50+25) / 2 to find the average homeworks mark.

thnx for reply anyway...[code from your post before] will calculate (50+25) / 2 to find the average homeworks mark.

thnx for reply anyway...

Real caused detected : it's the end-of-input file symbol "^Z", I thought it just end the current cin(input) loops, but it actually it closed EVERY input stream of the program...

Ouch, It seems I need to take care about input too other than the code itself...

so, just done some recoding and this is the WORKING code... ^0^

/* 3-5. Write a program that will keep track of grades for several students at once.
 * The program could keep two vectors in sync: The first should hold the student's names,
 * and the second the final grades that can be computed as input is read. For now,
 * you should assume a fixed number of homework grades. We'll see in §4.1.3/56
 * how to handle a variable number of grades intermixed with student names.
 */

#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::setprecision;
using std::streamsize;
using std::string;
using std::vector;

int main()
{

    // delaring needed variable; for main scope to keep the value until end program.
    vector<string> student_name;
    vector<double> overall_grade;

    // main device; input name and grade into variable.
    for (unsigned int student_counter = 1; student_counter == 1; ++student_counter)
    {

        if (student_counter == 1)
        {
            cout << endl << endl << "Insert student\'s name: ";
            string name_input;
            cin >> name_input;
            student_name.push_back(name_input);

            // collecting grade data
            cout << "Insert his/her midterm\'s grade: ";
            double midterm_grade;
            cin >> midterm_grade;

            cout << "Insert his/her final\'s grade: ";
            double final_grade;
            cin >> final_grade;

            int num_counter = 0;
            double homework_sum = 0;
            int homework_counter = 1;

            while (homework_counter == 1)
            {
                cout << endl << "Insert his/her homework's grade: ";
                double homework_input;
                cin >> homework_input;
                homework_sum = homework_sum + homework_input;

                // add more homework
                cout << "Want to add more homework grade?(yes/no): ";
                string add_homework;
                cin >> add_homework;

                if (add_homework == "yes")
                {

                    homework_counter = 0;
                }

                ++homework_counter;
                ++num_counter;
            }

            double homework_average = homework_sum / num_counter;

            // combining data.
            double grade_sum = (0.2*midterm_grade + 0.4*final_grade + 0.4*homework_average);

            // classify the combined data.
            overall_grade.push_back(grade_sum);
        }

        //Add more students
        cout << endl << endl << endl << "Want to add more student?(yes/no): ";
        string add_student;
        cin >> add_student;

        if (add_student == "yes")
        {
            student_counter = 0;
        }
    }

    // define a type for listing element in integer.
    typedef vector<double>::size_type ele_num;

    // define a variable to define amount of element in the set.
    ele_num ele_name_size = student_name.size();
    ele_num ele_grade_size = overall_grade.size();

    // detecting input (name and grade)
    if (ele_name_size == 0)
    {
        cout << endl << "You are not inserting any student\'s name, try again.";
        return 1;
    }

    if(ele_grade_size == 0)
    {
        cout << endl << "You are not inserting any grade data of student, try again.";
        return 1;
    }

    // seperate result from input
    cout << endl  << endl << endl;

    // accessing the data stored.
    for (unsigned int list_counter = 0; list_counter < ele_name_size && list_counter < ele_grade_size; ++list_counter)
    {
        // writing the data
        streamsize prec = cout.precision();
        cout << student_name[list_counter] << "\'s overall grade: " << setprecision(3) <<
                overall_grade[list_counter] << setprecision(prec) << endl;
    }

    // sepeerate result from 'return value'
    cout << endl << endl << endl;

    return 0;
}

thnx for everyone's that helping, learn so much thing from this one exercise, start to loving Acccelerated C++, and of course, the community of the board... xD

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.