How do I modify my code to organize objects and write them to a file.

Ok... i'm stuck here... I have a class called Items that creates an object with three attributes (MeshNumber, MaterialNumber, and name). I then have another class called materialList that takes the objects and adds it to the list. For example:

Items:
1
2
3
4
5
Justin(name:"Justin", MeshNumber:99, MaterialNumer:66) 
Katty(name:"Katty", MeshNumber:14, MaterialNumer:34)
John(name:"John", MeshNumber:13, MaterialNumer:47), 
Justin(name:"Justin", MeshNumber:78, MaterialNumer:20)
Mikal(name:"Mikal", MeshNumber:99, MaterialNumer:47)


materialList:
[Justin,Katty,John,...]

Each object is created according to the user input and is automatically add to the materialList list. The object's attributes in the list are then written onto a file in the following format(materialNumber meshNumber name):
1
2
3
4
17 35 "Justin"
40 19 "katty"
17 34 "mike"
3  9  "Mikal"

....

with each word separated by spaces.


I want to modify my code to so that the attributes are printed according to material number on a file organized by material number. For example:

Enter material number: 17

1
2
3
Material Number: 17
Mesh Number: 34 35
Name: Mike Justin 


Enter mateial number: 40

1
2
3
Material Number: 40
Mesh Number: 19
Name: Katty 



I think I am suppose to create different objects with the above attributes, but I do not know how to organize them in the way stated above.

My code:
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include<iostream> 
using std::cerr;
using std::endl;
#include <list>
using namespace std; 
#include <fstream>
using std::ofstream;
#include <cstdlib> // for exit function
#include <sstream>
#include <string>
using namespace std;

class Item{

//Access specifer
public: //todo, private with get/set 
string item;
int meshNum;
int mNum;

//constructor 
public:
Item( int mNum,string item, int meshNum  ){
    this->item=item;
    this-> mNum= mNum;
    this-> meshNum= meshNum;
    
}

//Memeber functions
public: 
string getItem(){
    return item;
}
void setItem(string item){
    this->item = item;
}
int getMeshNum(){
    return this->meshNum;
}
void setMeshNum(int meshNum){
    this->meshNum= meshNum;
}

int getMNum(){
    return this->mNum;
}
void setMNum(int mNum){
    this-> mNum= mNum;
}

};
//____________________________________________

 class materialList{
// Access specifer
private: 
list <Item> items;
 
 //constructor 
 public:
/* materialList(){
     this->items = new list<Item>;
} */

 // Memeber fucntions
 public:
 void add( const Item& item)
 {
     items.push_back(item);
 }
//print my list
void Print()
 {
     ofstream outdata; // outdata is like cin
     outdata.open("blender.dat", std::ios::app); // opens the file
   if( !outdata ) { // file couldn't be opened
      cerr << "Error: file could not be opened" << endl;
      exit(1);
   }

    for (auto &i : items)
         outdata  << i.getMNum() << " "<<i.getMeshNum()<< " "<<i.getItem()<<endl;  
      
    outdata.close();
 
   
}
void search(ifstream& inFile, string fname){
    inFile.open(fname);
    if (inFile.is_open()){
        cout<< "Successfully opened file"<< endl;
    } else{
        cout<< "Failed to open file"<< endl;
        exit(-1);
    }
  string line;
  int word;
  int materialNum;
  istringstream iss;
  cout << "Enter a material number:";
  cin >> materialNum;
  int i=0;

  while(!inFile.eof()){
    // read line by line from the file
    getline(inFile,line);
    if(inFile.good()){
      // read word by word in line and place words in arr
      iss.clear(); // clear out state
      iss.str(line);
      iss >> word;
      if (word == materialNum){
      cout << line << endl;
    }

    //if (word == materialNum){
      //cout << line << endl;
    }

  }
}
    
};
    


Last edited on
It doesn't have to output exactly in that format. I just want to be able to organize the outputs by material number in some way.
I then have another class called materialList that takes the objects and adds it to the list

Avoid designing classes with materially (get it?) the same member functions as a piece of member data. For example, consider materialList. This is a list class whose sole purpose is to serve as a proxy to a std::list. It is easier and more direct to use a std::list.

If only one of a particular thing is ever created, don't design a class to represent it. One will have ample opportunity to do this extra work later when and if it's a good idea. For example, there is only one materialList in the entire program - so it may as well not exist at all.

If a class's get/set functions do nothing, the accessed data is effectively public. Just make it public.
Trivial getters and setters hinder comprehension. One can't say much of anything about the meaning of getThing(), and even less of the corresponding setter. But one can say everything there is to know about foo.thing = bar without more than a glance at foo. For example, item is about 40 lines long but it should be five:
1
2
3
4
5
struct item 
{
  std::string name;
  int mesh, material
};

This is an 90% reduction in code size & a 0% reduction in functionality. Each line of code represents a chance to get confused and a chance to make an error; less is more.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream> 
#include <string>
#include <algorithm>
#include <set>
#include <iterator>

struct item 
{
  std::string name;
  int mesh, material;
};

std::ostream& operator<<(std::ostream& s, item const& i) 
{ return s << i.material << ' ' <<i.mesh << ' ' << i.name << '\n'; }
std::istream& operator>>(std::istream& s, item& i) 
{ return s >> i.material >> i.mesh >> i.name; } 
bool operator<(item const& a, item const& b) 
{ return a.material < b.material; }

int main()
{ 
  std::multiset<item> items(std::istream_iterator<item>{std::cin}, {});
  std::copy(items.begin(), items.end(), std::ostream_iterator<item>{std::cout});
}

http://coliru.stacked-crooked.com/a/f6c66a7632032943
Last edited on
Can you go more into detail why you have the "&" at the end of things(i.e. ...ostream&,const&). Why do you do this and when do I know how to. Someone in other forum told me to include it in my code and I should've asked why.

Also, why did you include the const in item const& ostream, but not for istream. What is the const for?
Last edited on
Simply, the spec for operator<< (and operator>>) requires the stream to be passed by ref.

operator<< doesn't modify the data argument - and so is passed by const ref. If just passed by ref then the calling data has to be lvalue (can be modified) and not rvalue (eg "qwer"). If passed by const ref then both rvalue and lvalue allowed.

operator >> doesn't have const just ref as this function does modify the calling data.
Last edited on
Topic archived. No new replies allowed.