1

I'm trying to create a program that read and print students' data with c++. for that, I've created a struct Student, a function to read data from the user and assign it to a struct instance s1 and a function to print students' data on the screen, and I think the problem is with the function that read/write data.

Here is the my code:

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

struct Student
{
    char name[30];
    int age;
    double gpa;
    string department;
};

Student read_data(Student x)
{
    cout << "Name (30 characters maximum): ";
    cin.get(x.name, 30);
    cout << "Age: ";
    cin >> x.age;
    cout << "Department: ";
    cin >> x.department;
    cout << "GPA: ";
    cin >> x.gpa;

    return x;
}

void print_data(Student x)
{
    cout << 
"\n***************************************************************" << endl;
    cout << "Name: " << x.name << endl;
    cout << "Age: " << x.age << endl;
    cout << "Department: " << x.department << endl;
    cout << "GPA: " << x.gpa << endl;
}

int main()
{
    Student s1, s2, s3;

    cout << "This program stores -Temporarily- data of three students\n" << endl;

    cout << "Enter 1st student's data" << endl;

    read_data(s1);

    print_data(read_data(s1));

    system("pause");
    return 0;
}

The output of this code is:

This program stores data of three students

Enter 1st student's data
Name (30 characters maximum): Ahmed Maysara
Age: 22
Department: CS
GPA: 3.5
Name (30 characters maximum): Age: Department: GPA:
***************************************************************
Name:
Age: -858993460
Department:
GPA: -9.25596e+61
Press any key to continue . . .

As you see, the output is out of my expectations :) ..

Any help ?!

4
  • 3
    Try reading about pass-by-value and pass-by-reference Commented May 21, 2019 at 3:40
  • 1
    Calling read_data(s1); (multiple times for s1) without utilizing the return to store the data somewhere, seems a bit self-defeating. Commented May 21, 2019 at 3:48
  • The bug is very likely in the rest of the code, judging by the way you handle copies as if they were references. Commented May 21, 2019 at 4:07
  • @DavidC.Rankin .. Do you know what?! .. maybe you're so good .. or I'm so bad .. Thanks .. the problem has been solved :D .. Commented May 21, 2019 at 4:13

4 Answers 4

1

Both CinCout and David are correct. There are a couple of problems with your code as it now stands. The first problem is that while you successfully call the function read_data(s1), s1 is a just a copy. So, when the function sets all of the values for the student using cin, it is really just setting a copy's values. You can either make it so that you are passing in the original, or you can return the student (which you are doing) and set s1 equal to the result (which you are not).

To make sure that you pass in the original, you can go to where you declared read_data. Instead of saying Student read_data(Student x), you should place an ampersand after the parameter that you don't want to copy Student read_data(Student &x). This is called passing by reference (you reference the original instead of referencing by copy)

Alternatively, you could con just set s1 to the result where you call it in main. You could say s1 = read_data(s1); and that would work fine, though a bit more inefficiently.

Lastly, the other glaring error in the code is that you accidentally call read_data again when you say print_data(read_data(s1)). Instead, say print_data(s1).

Sign up to request clarification or add additional context in comments.

1 Comment

I've tried these solutions and everything is fine, so, thanks :D ... a bit comment, I can erase the line read_data(s1); and the line print_data(read_data(s1)) will satisfy the desired output ..
1

Instead of passing and returning the structure object each time on call of read_data and print_data we could add those inside the structure itself, We could create object of Student and call the functions read and print within the same.

struct Student
{
    char name[30];
    int age;
    double gpa;
    string department;

    Student(): age(0), gpa(0)
    {
        memset( name, 0, 30 );
    }

    void read()
    {
        cout << "\nName (30 characters maximum): ";
        cin.get(name, 30);
        cout << "\nAge: ";
        cin >> age;
        cout << "\nDepartment: ";
        cin >> department;
        cout << "\nGPA: ";
        cin >> gpa;
    }
    void print()
    {
        cout << "\n***************************************************************" << endl;
        cout << "Name: " << name << endl;
        cout << "Age: " << age << endl;
        cout << "Department: " << department << endl;
        cout << "GPA: " << gpa << endl;
    }
};

int main()
{
    Student s1;
    s1.read();
    s1.print();
    return 0;
}

Comments

0

You are passing copy of s1 into the read_data function, but not bothering to update the value based on the return arg. i.e. something like this should work.

s1 = read_data(s1);
print_data(s1);

Alternatively, pass by reference instead of value:

void read_data(Student& x)
{
    cout << "Name (29 characters maximum): "; // requires null terminator
    cin >> x.name; // just read into the buffer directly
    cout << "Age: ";
    cin >> x.age;
    cout << "Department: ";
    cin >> x.department;
    cout << "GPA: ";
    cin >> x.gpa;
}

And then later:

read_data(s1);
print_data(s1);

Comments

0

change you read_data with something like this

void read_data(Student& x)
{
    cout << "Name (30 characters maximum): ";
    ///cin.get(x.name, 30);
    cin.getline(x.name, 30);
    cout << "Age: ";
    cin >> x.age;
    cin.ignore();
    cout << "Department: ";
    std::getline(cin, x.department);
    ///cin >> x.department;
    cout << "GPA: ";
    cin >> x.gpa;
    cin.ignore();
    // return x; can't return a value from a void function
}

and in main function or where you are calling the read_data function use

Student s1, s2, s3;

cout << "This program stores -Temporarily- data of three students\n" << endl;

cout << "Enter 1st student's data" << endl;

read_data(s1);
read_data(s2);
read_data(s3);

the reason you are getting weird values in return is that you capture buffer with cin >> instead getline see

1 Comment

Don't return a value from a void method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.