IO files and Getter problem!

i have 2 class, unit and result. The unit have a function 'readData' that read from a file and write into the class variables. When i call the function from unit class eg. 'u.getUnitName()' i return the correct 'unitName' as per from the file.

But if i call the getUnitName from the result class, it return the 'unitName' from the 'Unit' class constructor.

readData function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  void Unit::readData(Unit& u)
{
    inFile.open("rinput.txt");

    inFile >> u.unitName >> u.unitId >> u.credits;

    u.unitName = unitName;
    u.unitId = unitId;
    u.credits = credits;

    outFile.open("routput.txt");
    outFile << "uname: " << u.unitName << '\n'
    << "uid: " << u.unitId << '\n'
    << "credits: " << u.credits << '\n';


    inFile.close();
    outFile.close();

}


The getter from result.cpp
1
2
3
4
5
6
string result::getUnitName() const
{
    string uName;
    uName = u1.getUnitName();
    return uName;
}


the main function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "result.h"

using namespace std;

int main()
{
    Unit u1;
    result r1;

    u1.readData(u1);
    cout << u1.getUnitName() << endl; 
    // return the correct unitName same as "rinput.txt".


    cout << r1.getUnitName() << endl;
    // return the unitName "nil" from 'unit' default constructor.
}


need advice on how can i retrieve the correct unitName from the getter in result class. My intention is to retrieve all the data from 'unit' and retrieve it in the 'result' class and there will be a 'writeData' function in it to write the unitName, read from the file for a variable call 'mark' and write and output into "routput.txt".

Last edited on
For void Unit::readData(Unit& u) it doesn't make sense to pass another Unit object. Just remove the u. within the function.


How does the the result class/struct looks like? If it has a member Unit u1; apply readData() to this:

r1.u1.readData(u1);
ok shall give it a try. My intention is to solve the issue on the get function in my result class first and moved on to expand my result class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "result.h"

#include <iostream>

using namespace std;

result::result()
{
    mark = 0;

}

void result::setMark(float m)
{
    mark = m;
}

float result::getMark() const
{
    return mark;
}

string result::getUnitName() const
{
    string uName;
    uName = u1.getUnitName();
    return uName;
}


.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifndef RESULT_H
#define RESULT_H

#include "unit.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

class result
{
    public:
        result();
        result( string uName, string uId, int cred, float m);

        // Getters
        int GetCredits() const;
        float getMark() const;
        string getUnitName() const;
        string getUnitId() const;

        //setters
        void SetCredits( int cred );
        void setMark(float m);


    private:
        ifstream inFile;
        ofstream outFile;

        float mark;

        Unit u1;
};

#endif // RESULT_H 
i've tried declaring 'unit u1' public in the result.h and call r1.u1.readData() in my main. The result was reverse. Now my 'u1.getUnitName()' return nil and my 'r1.getUnitName' return the unitName from the file.

What could be the explanation to this? As i couldnt understand the logic.

Thanks a million
In your original post, line 5 reads from "rinput.txt" into u.unitName. Then line 7 overwrites the value you just read in u.unitName with whatever is in this->unitName. The same is true for u.unitId and u.credits.

So the reason your getter "isn't working" may be because you've stored the wrong data in the first place.
dhayden i think i got your point. I tried to store the data in 'u' rather in the this->unitName. So that is why my getter isn't retrieving the data i wanted.

i tried expanding my result class, i tried to declare unitName, unitId, credits as private variables in my result class to store the data i retrieved from unit class. Am i on the right track? by re-creating similar var that has already been declared in unit class.

i thought that ofstream can be used in the same way as the ifstream in this case but i was wrong.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void result::writeData()
{
    outFile.open("routput.txt");

    outFile << unitName << unitId << credits;

    /*
    outFile << "uname: " << unitName << '\n'
    << "uid: " << unitId << '\n'
    << "credits: " << credits << '\n';
    */

    outFile.close();

}


i tried calling r1.getUnitName(), it return the correct data but once this function is called, the output is just some random numbers. No errors. Is this another case of wrong data storage again??
Could the following code be of any help?

Unit.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef UNIT_H
#define UNIT_H

#include <fstream>
#include <string>

class Unit
{
public:
    Unit();
    void readData();
    std::string getUnitName() const {return unitName;}

private:
    std::string unitName;
    std::string unitId;
    std::string credits;
};

#endif // UNIT_H 


Unit.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "Unit.h"

Unit::Unit()
{}

void Unit::readData()
{
    std::ifstream inFile;
    inFile.open("rinput.txt");

    inFile >> unitName >> unitId >> credits;
    inFile.close();

    std::ofstream outFile;
    outFile.open("routput.txt");
    outFile << "uName: " << unitName << std::endl
            << "uId: " << unitId << std::endl
            << "credits: " << credits << std::endl;
    outFile.close();
}


Result.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef RESULT_H
#define RESULT_H

#include <string>
#include <fstream>
#include "Unit.h"

class Result
{
public:
    Result();
    Result(std::string uName, std::string uId, int cred, float m);

    // Getters
    int GetCredits() const;
    float getMark() const;
    std::string getUnitName() const;
    std::string getUnitId() const;

    //setters
    void setCredits(int cred);
    void setMark(float m);
    void setUnit(const Unit& unit)
        {u1 = unit;}    // Bewere! Unit::Unit(unit&) missing!
                        // Potential issue if a pointer is to be copied

private:
    std::ifstream inFile;
    std::ofstream outFile;
    float mark;
    Unit u1;
};

#endif // RESULT_H 


Result.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "Result.h"

Result::Result()
{
    mark = 0;
}

void Result::setMark(float m)
{
    mark = m;
}

float Result::getMark() const
{
    return mark;
}

std::string Result::getUnitName() const
{
    return u1.getUnitName();
}


main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include "Result.h"

int main()
{
    Unit unit1;
    Result result1;

    unit1.readData();
    std::cout << unit1.getUnitName() << std::endl;
    result1.setUnit(unit1);
    std::cout << result1.getUnitName() << std::endl;
}


rinput.txt:
1
2
JohnSmith 13 Manythanks
AnnJohnson 666 Aknowledgements


routput.txt:
1
2
3
uName: JohnSmith
uId: 13
credits: Manythanks


output:
JohnSmith
JohnSmith
Press <RETURN> to close this window...

Last edited on
many thanks to you. But i still cannot figure out how to write to the file with the values gotten from unit class.

i tried declaring unitName, unitId , credits in my result.h and tried:
1
2
3
4
5
string result::getUnitName()
{
   unitName = unit1.getUnitName();
   return unitName;
}


and create a writeData function
1
2
3
4
5
6
7
8
9
void result::writeData()
{
    outFile.open("routput.txt");

    outFile << unitName;

    outFile.close();

}

my task given is to output unit information and mark as for each unit FROM the result class. So naturally i will think that the writeData function should exist.
Last edited on
how to write to the file with the values gotten from unit class.


Unit.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef UNIT_H
#define UNIT_H

#include <fstream>
#include <string>

class Unit
{
public:
    Unit();
    void readData();
    std::string getUnitName() const {return unitName;}
    std::string getUnitId() const {return unitId;}
    std::string getCredits() const {return credits;}

private:
    std::string unitName;
    std::string unitId;
    std::string credits;
};

#endif // UNIT_H 


Unit.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "Unit.h"

Unit::Unit()
{}

void Unit::readData()
{
    std::ifstream inFile;
    inFile.open("rinput.txt");

    inFile >> unitName >> unitId >> credits;
    inFile.close();
}


Result.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ifndef RESULT_H
#define RESULT_H

#include <string>
#include <fstream>
#include "Unit.h"

class Result
{
public:
    Result();
    Result(std::string uName, std::string uId, int cred, float m);

    // Getters
    int GetCredits() const;
    float getMark() const;
    std::string getUnitName() const;
    std::string getUnitId() const;

    //setters
    void setCredits(int cred);
    void setMark(float m);
    void setUnit(const Unit& unit)
        {u1 = unit;}    // Bewere! Unit::Unit(unit&) missing!
                        // Potential issue if a pointer is to be copied
    void outputResult();

private:
    std::ifstream inFile;
    std::ofstream outFile;
    float mark;
    Unit u1;
};

#endif // RESULT_H 


Result.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "Result.h"

Result::Result()
{
    mark = 0;
}

void Result::setMark(float m)
{
    mark = m;
}

void Result::outputResult()
{
    outFile.open("routput.txt");
    outFile << "uName: " << u1.getUnitName() << std::endl
            << "uId: " << u1.getUnitId() << std::endl
            << "credits: " << u1.getCredits() << std::endl;
    outFile.close();
}

float Result::getMark() const
{
    return mark;
}

std::string Result::getUnitName() const
{
    return u1.getUnitName();
}


main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include "Result.h"

int main()
{
    Unit unit1;
    Result result1;

    unit1.readData();
    std::cout << unit1.getUnitName() << std::endl;
    result1.setUnit(unit1);
    std::cout << result1.getUnitName() << std::endl;
    result1.outputResult();
}

i tried using the above code and set the getters/setters. But im back to my initial problem of the data not passing correctly between classes.

getters in my result class
1
2
3
4
5
6
7
8
9
string result::getUnitName() const
{
    return C.getUnitName();
}

string result::getUnitId() const
{
    return C.getUnitId();
}


result.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef RESULT_H
#define RESULT_H

#include <iostream>
#include <string>
#include "COURSE.H"

using namespace std;

class result
{
    public:
        result();
        result(string uName, string uId, int cred, float m);

        float getMark() const;
        string getUnitId() const;
        string getUnitName() const;
        int getCredits() const;

        void setMark(float m);

    private:
        float mark;

        Course C;

};

#endif // RESULT_H 


function in my unit class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
istream & operator >>( istream & input, Course & C )
{
    string unitName, unitId;
    int credits;

  input >> unitName >> unitId >> credits;

  C.setUnitName(unitName);
  C.setUnitId(unitId);
  C.SetCredits(credits);

  return input;
}

ostream & operator <<( ostream & os, const Course & C )
{
  os << "  Course:  " << C.getUnitName() << '\n'
     << "  Section: " << C.getUnitId() << '\n'
     << "  Credits: " << C.GetCredits() << '\n';
  return os;
}


unit.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef COURSE_H
#define COURSE_H

#include <iostream>
#include <string.h>  // C string library

using namespace std;

const unsigned CourseNameSize = 10;

class Course {
public:
    Course();
Course( string uName, string uId , int cred );

  int GetCredits() const; // Get the number of credits.
  string getUnitName () const;
  string getUnitId () const;

  void SetCredits( int cred ); // Set the number of credits.
  void setUnitName(string uName);
  void setUnitId(string uId);

private:
  string unitName;  // course name, C style string. not a C++ string object
  string unitId;   // section (letter) can be enrolment mode
  int  credits;   // number of credits
};

ostream & operator <<( ostream & os, const Course & C );
istream & operator >>( istream & input, Course & C );

#endif 


I stepped backwards to test my getters before proceeding to the IO. when i call for both getUnitName from the 2 classes it returns different values. I know that there might be a problem within the overloaded operator(im tasked to unfriend all the overloaded operator).

Am i right to say that the value is passed to the C.setUnitName(unitName) in the overloaded operator and is not set on the this->unitName therefore no matter how i call it from another class i got back the value from the default constructor?

if so is there any ways to call the values that are set in the overloaded operator over from another class?
function in my unit class
unit.h

Have you chosen to turn the name of class “Unit” into “Course”, but keeping the file name “unit.h” (all lowercases)? Or have you changed it in “COURSES.H” (all uppercases)?

#include <string.h>
Is there a specific reason why you like <string.h> better than <cstring>?

im tasked to unfriend all the overloaded operator

If a function is not friend of a class, it should not appear in a class header, IMHO.

1
2
3
4
string unitName;
string unitId; 
string getUnitName () const;
string getUnitId () const;

You are free to use the names you want, of course, but I think that now that your class name is “Course”, those identifiers are becoming misleading. Are you sure you’ll easily be able to re-read your code let’s say five months hence?

Giving us a minimum compilable code that we could comfortably copy and paste to make tests, along with some examples of your input and output files would make it *so* much easier to help you...
Topic archived. No new replies allowed.