Puppy Linux Discussion Forum Forum Index Puppy Linux Discussion Forum
Puppy HOME page : puppylinux.com
"THE" alternative forum : puppylinux.info
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

The time now is Tue 22 Jul 2014, 11:33
All times are UTC - 4
 Forum index » Off-Topic Area » Programming
C++ database coding attempt
Post new topic   Reply to topic View previous topic :: View next topic
Page 1 of 2 [20 Posts]   Goto page: 1, 2 Next
Author Message
Lobster
Official Crustacean


Joined: 04 May 2005
Posts: 15117
Location: Paradox Realm

PostPosted: Sun 04 Oct 2009, 12:02    Post subject:  C++ database coding attempt
Subject description: was: C++ reading an object - eh - how
 

I taught everything I knew about C++ (just above zero) to my programming buddy Shadow.
I don't think he has programmed in C++ before
but soon we had hacked the below program together
It writes an object to a file
but we can not seem to read it in as an object?

any help welcome Smile

The idea is to eventually marry this with other work
on pbase which we started some time ago

Code:
#include <fstream>
#include <iostream> 
using namespace std; 

class person { 
   protected: string name, fname; short age;
   
   public: string getFileName() {
      fname = name;
      fname.append(".dat");
      return fname;
   }

   public: string getName() {
      return name;
   }
            
   public: void getData(){ 
      cout << "Enter name: "; cin >> name; 
      cout << "Enter age: "; cin >> age;
    } 
};


int main() {
   //person newPerson;   
   //newPerson.getData();
   //char filename[80];
   //strcpy(filename, newPerson.getFileName().c_str());
   //ofstream outfile(filename, ios::binary); 
   //outfile.write(reinterpret_cast<char*>(&newPerson), sizeof(newPerson));
   
   char filename[80];
   cout << "Enter filename to read: "; cin >> filename;
   person oldPerson; 
   ifstream infile(filename, ios::binary);
   infile.read(reinterpret_cast<char*>(&oldPerson), sizeof(oldPerson));
   //cout << oldPerson.getName();
      
   return 0;
}

_________________
Puppy WIKI

Last edited by Lobster on Tue 06 Oct 2009, 22:36; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website 
Lobster
Official Crustacean


Joined: 04 May 2005
Posts: 15117
Location: Paradox Realm

PostPosted: Tue 06 Oct 2009, 03:45    Post subject:  

Very Happy Using emergency rations of sardines
we managed to solve this problem . . .
(Shadow did the programming, I tried to comprehend it)

So now we can write and read a potential database
Next stop vectors
- which I have a feeling are not vegetarian doctors

Smile

_________________
Puppy WIKI
Back to top
View user's profile Send private message Visit poster's website 
Lobster
Official Crustacean


Joined: 04 May 2005
Posts: 15117
Location: Paradox Realm

PostPosted: Tue 06 Oct 2009, 15:15    Post subject:  

OK here is the code so far
(console database pre alpha for Puppy)
the 'add' option is the only one implemented
and we are getting a segmentation error
- any clues on curing that?

Code:
#include<iostream>
#include<fstream>
#include<vector>
#include<string>
using namespace std;

class Person {
   string field[3];
   //vector<string> field;
   
   public:
   Person(){}
   Person(string n, string a, string e) {field[0] = n; field[1] = a; field[2] = e;}
   Person(string f[3]) {field[0] = f[0]; field[1] = f[1]; field[2] = f[2];}
   ~Person(){}
   
   void SetValue(int id,string n) {field[id] = n;}
   string GetValue(int id) {return field[id];}
};

class PersonCollection {
   vector<Person> PersonsList;
   
   public:
   PersonCollection(){}
   ~PersonCollection(){PersonsList.clear();}
   
   void Add(Person p) {PersonsList.push_back(p);}
   int Size() {return PersonsList.size();}
   Person Item(int i) {return PersonsList[i];}
   int compare(int id,Person p1,Person p2) {if(p1.GetValue(id) > p2.GetValue(id)) return 1;if(p2.GetValue(id) > p1.GetValue(id)) return 2;return 0;}
   
   void Sort(){
      Person tmp;
      for(int i=0;i<Size();i++) {
         for(int j=0;j<Size()-1-i;j++) {
            if(compare(0,PersonsList[j],PersonsList[j+1]) == 1) {
               tmp = PersonsList[j];
               PersonsList[j] = PersonsList[j+1];
               PersonsList[j+1] = tmp;
            }
         }
      }   
   }
   Person Find(int id, string s){
      for(int i=0;i<Size();i++) {
         if(PersonsList[i].GetValue(id).compare(s) == 0) return PersonsList[i];
      }
      return Person();
   }

};

class PersonFileProcessor {
   char* file;
   public:
   PersonFileProcessor(char* f) {file = f;}
   ~PersonFileProcessor(){}
   
   void Save(PersonCollection addressbook) {
      ofstream out(file, ios::app);
      out.write((char*) &addressbook, sizeof(addressbook));
      out.close();
   }
   
   PersonCollection Read() {
      PersonCollection addressbook;
      ifstream in(file);
      in.read((char*) &addressbook, sizeof(addressbook));
      in.close();   
      return addressbook;   
   }   

};

int main(int argc, char *argv[])
{
   system("clear");
   
   PersonFileProcessor pp((char*)"Address.dat");
   
   string name, address, email, inputmenu;
      cout << "A=Add Records F=Find Records S=Search Records T=Table Display" << endl; cin >> inputmenu;
      if(inputmenu == "A" || inputmenu == "a")
         {
      cout << "Enter Name:" << endl; cin >> name;
      cout << "Enter Address:" << endl; cin >> address;
      cout << "Enter Email Address:" << endl; cin >> email;
      PersonCollection addressbook;
     Person p1(name, address, email);
     addressbook.Add(p1);
     pp.Save(addressbook);   
          }
          if(inputmenu == "F" || inputmenu == "f")
         {
            cout << "Search for name:" << endl; cin >> name;
            PersonCollection addressbook = pp.Read();
            cout << "Size:" << addressbook.Size() << endl;
            Person p1 = addressbook.Find(0,name);
            cout << "Name:" << p1.GetValue(0) << endl;
            cout << "Address:" << p1.GetValue(1) << endl;
            cout << "Email:" << p1.GetValue(2) << endl;
      }
   
   return 0;
}

_________________
Puppy WIKI
Back to top
View user's profile Send private message Visit poster's website 
tronkel


Joined: 30 Sep 2005
Posts: 1101
Location: Vienna Austria

PostPosted: Tue 06 Oct 2009, 16:58    Post subject:  

Gosh that's a valiant attempt - but in order to write a database of Person objects and store them in a list, you really could make more use of the STL and its very useful iterator classes rather than attempting to do stuff in the old-fashioned slow way using char * etc. STL <string> is also much less error-prone than char *. Confirmed by Bjarne Stroustrup, the creator of C++

Yes, I know that kernel space specialists frown on using C++ inside the kernel itself, but in user space it is a god-send for stuff like hacking together databases.

For storing the Person list, I would go for an STL <list> rather than the <vector> as used here. <list> while maybe being a tad less efficient in theory, is more robust in practice than the likes of <vector>

You can grab a <list> iterator thus:

Quote:
//declare and initialise the list iterator
list<Person>::iterator li=personList.begin();

//loop through the personList until you find what you are looking for:

for(;li !=personList.end();i++)
{
//your search code goes here
}



You could use serialisation to store you objects to hard disk. This is really the best way to do it, but for this relatively simple structure, a text file containing lines of text strings is maybe the best compromise here.

The main menu would be better implemented using the switch statement- again less error-prone.

I'll try to cobble some code together at the weekend. In the meantime, read up on the above techniques in say Deitel and Deitel.

_________________
Life is too short to spend it in front of a computer
Back to top
View user's profile Send private message Visit poster's website AIM Address 
Lobster
Official Crustacean


Joined: 04 May 2005
Posts: 15117
Location: Paradox Realm

PostPosted: Tue 06 Oct 2009, 22:34    Post subject:  

Quote:
Gosh that's a valiant attempt


Thanks Jack Smile
Appreciate very much the comments.
We (Shadow + Lobster making tea) are very grateful.
Basically 80% of the time is spent looking for samples on the web, which then somehow
- only his third day programming in C++ Shadow manages to tweak, modify and improve . . .

We may well go from vector to list
- we did consider using 'map' but dropped that

_________________
Puppy WIKI
Back to top
View user's profile Send private message Visit poster's website 
tronkel


Joined: 30 Sep 2005
Posts: 1101
Location: Vienna Austria

PostPosted: Wed 07 Oct 2009, 14:40    Post subject:  

Ok Ed, here is a start on your Contacts Database.
Copy the code from here into three correspondingly named files and stick them into a folder on your system

Open a terminal in that folder and compile the project with the command:

Quote:
g++ -g contact.cpp main.cpp


main.cpp
Quote:
#include "contact.h"
#include <iostream>

using namespace std;

int main()
{
//temporary code for testing Contact class
Contact newcontact("Lobster", "fishtank", "carp@tank.com");
cout << newcontact.returnName() << endl;
cout << newcontact.returnAddress() << endl;
cout << newcontact.returnEmail() << endl;

return 0;

// todo:
// create a file controller class that saves and loads data at program startup
// best place for loading data is the constructor for a main program object
// create a main database class that holds a list of contacts. Use an STL list<Contact> object for this
// code the database search function (using a list<Contact>::iterator)
// create a user menu



}


contact.h

Quote:
#ifndef CONTACT_H
#define CONTACT_H

#include <string>
using namespace std;


class Contact
{//class definition for Contact object

private:

string name;
string address;
string email;

public:

Contact(); //default constructor
Contact(string, string, string); //parameterised constructor

string returnName();
string returnAddress();
string returnEmail();






};

#endif


contact.cpp

Quote:
#include "contact.h"
#include <string>

using namespace std;


Contact::Contact()
{ }

Contact::Contact(string aname, string anaddress, string anemail)
{// definition of Contact object constructor

name=aname;
address=anaddress;
email=anemail;

}


string Contact::returnName()
{
return name;

}


string Contact::returnAddress()
{
return address;

}


string Contact::returnEmail()
{
return email;

}


Study this code. Sequel to follow at the weekend!

_________________
Life is too short to spend it in front of a computer
Back to top
View user's profile Send private message Visit poster's website AIM Address 
Lobster
Official Crustacean


Joined: 04 May 2005
Posts: 15117
Location: Paradox Realm

PostPosted: Wed 07 Oct 2009, 15:25    Post subject:  

studying it - creating external class is useful Smile
many thanks

_________________
Puppy WIKI
Back to top
View user's profile Send private message Visit poster's website 
Lobster
Official Crustacean


Joined: 04 May 2005
Posts: 15117
Location: Paradox Realm

PostPosted: Wed 07 Oct 2009, 20:57    Post subject:  

Quote:
g++ -g contact.cpp main.cpp


I am assuming -g 'groups' the two files into one run time but I can find no reference to it on google?

_________________
Puppy WIKI
Back to top
View user's profile Send private message Visit poster's website 
tronkel


Joined: 30 Sep 2005
Posts: 1101
Location: Vienna Austria

PostPosted: Thu 08 Oct 2009, 02:56    Post subject:  

@Ed

The -g option for has nothing to do with grouping the files to be compiled.


The -g option for g++ tells the compiler to build an executable that contains/includes degugging information. This is necessary in case you need to run the GNU debugger called GDB on your source code in the event of having bugs that are difficult to track down.

Once the final version of the program has been built and tested, you can then recompile the project without the -g option and thereby have a smaller executable - i.e. without the superfluous degugging information.

_________________
Life is too short to spend it in front of a computer
Back to top
View user's profile Send private message Visit poster's website AIM Address 
Lobster
Official Crustacean


Joined: 04 May 2005
Posts: 15117
Location: Paradox Realm

PostPosted: Thu 08 Oct 2009, 03:53    Post subject:  

Thanks Jack

We did use the debugger from the command line
(when we got the segmentation fault)
but could not make much from the data created

Smile

_________________
Puppy WIKI
Back to top
View user's profile Send private message Visit poster's website 
tronkel


Joined: 30 Sep 2005
Posts: 1101
Location: Vienna Austria

PostPosted: Thu 08 Oct 2009, 06:51    Post subject:  

The debugger is only of use in certain circumstances. You need to learn to use the debugger in conjunction with setting watch expressions as well.

There a several good tools available in Puppy that can help. There is a version of Emacs for Puppy available as a pet package somewhere in the forum. This allows you to edit your code and debug it in the same window.

Not sure about Geany - I don't think it can do that.
Other tools are Codeblocks and Netbeans (needs Java though).

There is also an sfs for Anjuta as well that would be suitable

_________________
Life is too short to spend it in front of a computer
Back to top
View user's profile Send private message Visit poster's website AIM Address 
tronkel


Joined: 30 Sep 2005
Posts: 1101
Location: Vienna Austria

PostPosted: Fri 09 Oct 2009, 11:48    Post subject:  

Hi Ed,

I've just been looking at that original C++ code you posted here.
After I added #include <stdlib.h> it compiled fine.

Tried adding a few records and that seemed to work OK - but when I tried to do a search, it bombed straight out as if it was unable to access the file properly.

On studying that code, whoever wrote it. has used the in.Read() way of doing things that I have never used much in the past. I have a feeling that this function cannot retrieve type information - i.e. only data information using this method. This would certainly make it crash. Would be an interesting task to fix this, but this would mean having to alter the program somewhat.

I'll play with this original code some more and also enhance the program to do searching etc. using a purely STL method as originally suggested.

Keep going with it.

Jack

_________________
Life is too short to spend it in front of a computer

Last edited by tronkel on Tue 13 Oct 2009, 16:12; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website AIM Address 
Lobster
Official Crustacean


Joined: 04 May 2005
Posts: 15117
Location: Paradox Realm

PostPosted: Fri 09 Oct 2009, 12:13    Post subject:  

I
Quote:
've just been looking at that original C++ code you posted here.


Thanks Tronkel

Shadow did some minor mods - added your list ideas Smile
but we won't be doing any coding until Monday
(Shadow is on holiday - his job is MS programmer)

Anyways any improvements and suggestions welcome

Smile

_________________
Puppy WIKI
Back to top
View user's profile Send private message Visit poster's website 
Lobster
Official Crustacean


Joined: 04 May 2005
Posts: 15117
Location: Paradox Realm

PostPosted: Sun 11 Oct 2009, 23:15    Post subject:  

Quote:
Other tools are Codeblocks and Netbeans (needs Java though)


I added the 'LXRAD GUI' from the puppy package manager in 4.3.1 release cndidate. When I looked at this previously it was completely unstable but may have been improved/recompiled. Anyway that seems sufficient to what we may need in the future. Smile

_________________
Puppy WIKI
Back to top
View user's profile Send private message Visit poster's website 
BarryK
Puppy Master


Joined: 09 May 2005
Posts: 7047
Location: Perth, Western Australia

PostPosted: Mon 12 Oct 2009, 04:06    Post subject:  

Lobster wrote:
Quote:
Other tools are Codeblocks and Netbeans (needs Java though)


I added the 'LXRAD GUI' from the puppy package manager in 4.3.1 release cndidate. When I looked at this previously it was completely unstable but may have been improved/recompiled. Anyway that seems sufficient to what we may need in the future. Smile


Nah, it's the same old Lxrad PET package. I haven't looked at it since I did so originally. As I recall, it had bugs.

The author stated that he was bewildered by GTK libs and was going to move Lxrad to using Wxwidgets, but I don't know if that ever happened, or even if he did anything more on the Lxrad project.

_________________
http://bkhome.org/news/
Back to top
View user's profile Send private message Visit poster's website 
Display posts from previous:   Sort by:   
Page 1 of 2 [20 Posts]   Goto page: 1, 2 Next
Post new topic   Reply to topic View previous topic :: View next topic
 Forum index » Off-Topic Area » Programming
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group
[ Time: 0.1172s ][ Queries: 12 (0.0063s) ][ GZIP on ]