Trying to learn from code, need help

what does this code do? What is a vector? What is sprintf?

Page 1 of 1

13 Replies - 919 Views - Last Post: 02 February 2010 - 06:51 PM Rate Topic: -----

#1 RLB31384  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 97
  • Joined: 29-January 10

Trying to learn from code, need help

Posted 01 February 2010 - 02:17 PM

I got this program code from the net, and im trying to modify it a bit and understand the parts that I haven't learned. I was trying to put all the functions in the Implementation file, but I can't seem to compile right when I do that. All the functions are in the header in this code. And I tried to paste them into the implementation file and then put the function definitions in the header. Can anyone help me with this? Also I know this is asking a lot, but could anyone explain what each line of the code does and what I would need to research to learn it...You can skip the more simple stuff...as I know its a lot to ask unless someone just doesnt mind. I have never used vectors so I need to research that, that should help me understand this better. I have also never used sprintf, what does this do? This line confuses me a bit its line 174: sprintf(szItemLine, "%12.12s %3d @ %6.2lf %-2.2s %7.2lf",

What is this line doing...Im guessing I need to research sprintf to understand what the numbers are doing? This line also confuses me, its line 144: friend ostream& operator<<(ostream& o, CInventory &item)

Im not sure at all what this line does at all.. If someone could just explain the more complicated things, that would be great.
Thanks!

Heres the code:

// Inventory.h: interface for the CInventory class.
//
//////////////////////////////////////////////////////////////////////

#include <iostream>
#include <iomanip>
#include <string>
#include <istream>
#include <fstream>
#include <vector>
#include <ctime>

using namespace std;
class CInventory  
  {
  private:
	static double iCustomerCounter;  // counts receipts (valid or invalid) issued
	static const char *szError[]; // check enum error_msg
	static const double dblTaxes; // i.e 7.5%

	long lInventory;
	string strDescription;
	double dblPrice;
	char cTax;
  public:
	enum error_msg {NOT_FOUND, IS_DUPLICATE, E_QUANTITY};
	// methods
	const long& get_inventory() const {return lInventory;}
	const string& get_description() const {return strDescription;}
	const double& get_price() const {return dblPrice;};
	const char& get_tax() const {return cTax;}
	// construction / destruction
	// default constructor
	CInventory::CInventory() : lInventory(10000), strDescription(""), dblPrice(0.0), cTax('N'){}
	// copy constructor
	CInventory(const CInventory &inv) {*this = inv;}
	virtual CInventory::~CInventory(){lInventory = 0; dblPrice = 0.0; cTax = 'N'; strDescription = "";}

	void init()
	{
	lInventory = 0;
	dblPrice = 0.0;
	cTax = 0;
	strDescription = "";
	}
  // copies information from inv to *this
	void operator=(const CInventory &inv)
	  {
	  lInventory = inv.get_inventory();
	  strDescription = inv.get_description();
	  dblPrice = inv.get_price();
	  cTax = inv.get_tax();
	  }
  
	// compares *this with item
	bool operator==(const CInventory &item)
	  {
	  return item.get_tax() == cTax && 
			 item.get_price() == dblPrice && 
			 item.get_description() == strDescription && 
			 item.get_inventory() == lInventory;
	  }

	// checks whether item numbers is present along a vector
	friend bool is_inventory(vector<CInventory>& inv, const int&iNo)
	  {
	  for (int i = 0; i < inv.size(); i++) {
		if (inv[i].lInventory == iNo) 
		  return true;
		}
	  return false;
	  }

	// checks for duplicated items along a vector
	friend bool is_duplicate(vector<CInventory>& inv, const CInventory& invCheck)
	  {
	  for (int i = 0; i < inv.size(); i++) {
		if (inv[i] == invCheck) 
		  return true;
		}
	  return false;
	  }

	// checks whether tax flag is T
	bool is_taxable()
	  {
	  return cTax == 'T';
	  }

	// fills one CInventory item from i.e. invent.dat
	friend istream& operator>>(istream& input, const CInventory &item)
	  {
	  operator>>(input, (CInventory &)item);
	  }
	friend istream& operator>>(istream& input, CInventory &item)
{
long lInventory = 0;
string strDescription = "";
double dblPrice = 0.0;
char cTax = 0;
// default item to empty
item.init();
if (!input.eof()) {
input >> lInventory >> strDescription >> dblPrice >> cTax;
// A complete inventory item has all these information: in case not, the input will fail
// and the variables will keep their values!!!!!!
if (lInventory != 0 && strDescription != "" && dblPrice != 0.0 && cTax != 0) {
item.lInventory = lInventory;
item.strDescription = strDescription;
item.dblPrice = dblPrice;
item.cTax = cTax;
}
}
return input;
}

	static string get_heading()
	  {
	  string strReturn = CInventory::get_printdate();
	  strReturn += "\n";
	  strReturn += "Customer ";
	  CInventory::iCustomerCounter;
	  strReturn += CInventory::iCustomerCounter + '0';
	  strReturn += "\n===================================================\n\n";
	  return strReturn;
	  }
	static void customerCounter()
	{
		++CInventory::iCustomerCounter;
	}
	static string get_footer(double dblSum, double dblTaxes)
	  {
	  char szFooter[512];
	  sprintf(szFooter, "\n%s\nSub Total: %10.2lf\nTaxes	: %10.2lf\n%s\nTotal	: %10.2lf\n%s\n",		
					  "---------------------------------------------------",
					  dblSum, 
					  dblTaxes, 
					  "---------------------------------------------------",
					  dblSum + dblTaxes,
					  "===================================================");
	  string strRet = szFooter;
	  return strRet;
	  }
	friend ostream& operator<<(ostream& o, CInventory &item)
	  {
	  o << setw(5)  << item.get_inventory() << " " << setw(12) << item.get_description() << setw(8) << fixed << setprecision(2) << item.get_price() << " " << item.get_tax();
	  return o;
	  }
	// calculates print date and time
	static string get_printdate()
	  {
	  struct tm *today;
	  char tmpbuf[128];
	  string strDate;
	  time_t ltime;
	  time(&ltime);
	  today = localtime( &ltime );
	  strftime( tmpbuf, sizeof(tmpbuf), "%b %d, %Y  %I:%M", today );		
	  strDate = tmpbuf;

	  return strDate;	  
	  }

	// returns a line item on the customer receipt
	static string get_item(CInventory &item, const int& iQuantity, double& dblPTax, double &dblSum)
	  {
	  string strReturn;
	  char szItemLine[256];
	  memset(szItemLine, 0, sizeof(szItemLine));
	  string strD = item.get_description();
	  double dblP = item.get_price();
	  string strTax = item.is_taxable() ? " TX" : " N";	  

	  sprintf(szItemLine, "%12.12s %3d @ %6.2lf %-2.2s %7.2lf", 
		strD.c_str(), 
		iQuantity,
		dblP,
		strTax.c_str(),
		iQuantity * dblP);
	  dblSum+= iQuantity * item.get_price();
	  if (item.is_taxable()) {
		dblPTax += dblTaxes * (iQuantity * item.get_price());
		}
	  strReturn = szItemLine;
	  return strReturn;
	  }

	// returns one of three existing errors
	static string get_error(int idx, long lInventory)
	  {
	  string strReturn;
	  char szErr[256];
	  if (idx >= NOT_FOUND || idx <= E_QUANTITY){
		//sprintf(szErr, "*** item %ld %s ***", lInventory, idx == NOT_FOUND ? "not found!" : idx == IS_DUPLICATE ? "duplicate in Inventory!" : "wrong quantity!" );
		sprintf(szErr, szError[idx], lInventory);
		strReturn = szErr;

		}
	  return strReturn;
	  }

	// performs requested error handling and prints an error message line rather
	// than an item line, in case
	// a) item not found
	// B)/> item duplicated
	// c) quantity related error (i.e. less than one)
	static string find_item(vector<CInventory>& inv, const long& lInventoryNo, const int& iQuantity, double& dblPTax, double& dblPSum)
	  {
	  string strReturn;
	  bool bFound = false, 
		bDuplicate = false, 
		bQuantity = iQuantity > 0;
	  int iFound = 0;
	  if (!bQuantity) {
		strReturn = get_error(E_QUANTITY, lInventoryNo);
		}
	  for (int i = 0; i < inv.size(); i++) {
		if (inv[i].get_inventory() == lInventoryNo) {
		  if (bFound) {
			if (strReturn.length() > 0) {
			  strReturn += "\n";
			  }
			strReturn += get_error(IS_DUPLICATE, lInventoryNo);
			bDuplicate = true;
			}
		  else {
			bFound = true;
			iFound = i;
			}
		  }
		}
	  if (!bDuplicate && bQuantity && bFound) {
		strReturn = get_item(inv[iFound], iQuantity, dblPTax, dblPSum);
		}
	  if (!bFound) {
		strReturn = get_error(NOT_FOUND, lInventoryNo);
		}
	  return strReturn;
	  }
};



// Inventory.cpp: implementation of the CInventory class.
//
//////////////////////////////////////////////////////////////////////

#include "Inventory.h"

const double CInventory::dblTaxes = 0.075;
// each time the program terminates this counter resets to 0
// clean solution could be to create a date dependency and
// write intermediate results to a i.e. file
double CInventory::iCustomerCounter = 0;
const char *CInventory::szError[] = 
  {
  "%ld is not in inventory",
  "%ld has duplicate inventory #",
  "%ld QUANTITY less than 1"
  };



// POS.cpp : Defines the entry point for the console application.
//

#include "Inventory.h"
#include <iostream>
#include <istream>
#include <fstream>

int main(int argc, char* argv[])
  {
  CInventory::customerCounter();
  filebuf fbInventory;
  fbInventory.open ("invent.dat",ios::in);
  filebuf fbReceipt;
  fbReceipt.open("receipt.dat", ios::out);
  istream inv(&fbInventory);
  ostream rec(&fbReceipt);
  vector<CInventory> v;
  CInventory item;

  // Get the inventory from the inventory file
  while(!inv.eof()) {
	inv >> item;
	if (item.get_description() != "") {
	  v.push_back(item);
	  }
	}

  // some debug output !
  for (int i = 0; i < v.size(); i++) {
	cout << v[i] << endl;
	}
  rec << CInventory::get_heading();
  cout << CInventory::get_heading();

  char input;
  long lInventoryNo = 0;
  int iQuantity = 0;
  double dblTax = 0.0;
  double dblSum = 0.0;
  string strOutput = "";
  do {
	input = 0;
	lInventoryNo = 0;
	iQuantity = 0;
	
	cout << "Enter Inventory No plus Quantity separated by space > ";
	cin >> lInventoryNo >> iQuantity;
	if (iQuantity != 0) {
	  input = 'y';
	  strOutput = item.find_item(v, lInventoryNo, iQuantity, dblTax, dblSum);
	  cout << strOutput << endl;
	  rec << strOutput << endl;
	  }
	else {
	  rec << CInventory::get_footer(dblSum, dblTax);
	  cout << CInventory::get_footer(dblSum, dblTax);
	  cout << endl << "Help another customer > ";
	  cin >> input;
	  if (tolower(input == 'y')) {
		CInventory::customerCounter();
		rec << CInventory::get_heading();
		cout << CInventory::get_heading();
		dblSum = 0.0;
		dblTax = 0.0;
		}
	  }
	cin.ignore();
	}while(tolower(input) == 'y');
  system("pause");
	return 0;
  }



**Mod Edit: Added description to the title**

This post has been edited by JackOfAllTrades: 02 February 2010 - 06:25 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Trying to learn from code, need help

#2 japanir  Icon User is offline

  • jaVanir
  • member icon

Reputation: 1010
  • View blog
  • Posts: 3,025
  • Joined: 20-August 09

Re: Trying to learn from code, need help

Posted 01 February 2010 - 03:27 PM

I bet there are a lot of nice DIC members who are willing to help but get a bit frightened by the length of the code..
i suggest that you be more specific on what you want explanations on, and what exactly is you dont understand.
Thanks for helping us, help you :)
Was This Post Helpful? 0
  • +
  • -

#3 DingleNutZ  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 121
  • Joined: 02-May 09

Re: Trying to learn from code, need help

Posted 01 February 2010 - 03:29 PM

i suggest you go and download an ebook from the net, quite a lot are free.
then read the book, study it a bit and understand what stuff does.
now if you can think logically, sit a look at the code, read over it and try to uderstand it line by line. you should know what the program does to help you figure it out.
i will help:
  // some debug output !
  for (int i = 0; i < v.size(); i++) {
	cout << v[i] << endl;
	}


first line: just a comment, making a reference to the code
line 2:starts a for loop, it initilizes the variable i as an integer with the value of 0. it checks that the variable i is less than v.size() (a variable from a class im guessing, i havnt played with c++ in a while) and if i is less than v.size it will add one to the value of i, it will then complete line 3 then it will check back to see if i is less than v.size(), and it will keep completing that until it returns false (i => v.size())
line 3:on this line the code is executed as part of the for code it will cout (call out i think is what it stands for, not too sure) the array value v[i], i is whatever it was in the for event before the cout was executed. when it has printed the array, it goes to a new line ready to print

hope this helps ya
Was This Post Helpful? 0
  • +
  • -

#4 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6078
  • View blog
  • Posts: 23,546
  • Joined: 23-August 08

Re: Trying to learn from code, need help

Posted 01 February 2010 - 03:37 PM

Here is a full reference on sprintf. It was the second link in a Google search for...sprintf.
Was This Post Helpful? 0
  • +
  • -

#5 RLB31384  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 97
  • Joined: 29-January 10

Re: Trying to learn from code, need help

Posted 01 February 2010 - 08:25 PM

Thanks for the replies..and yeah I figured the code would...I just wanted to put it there if people wanted to try it out. Can anyone explain to me what I need to do to move the functions over to the implementation file? I tried to move all the public functions over there, and then I took the function header and pasted them back into the public section of the spec file..wouldn't work, is there something I am forgetting?

Thanks for the link on sprintf, it helps a lot. Most of the lines in the program I am fine with. I know loops and stuff..all the basic stuff. I am a bit new at object oriented. I have wrote a few smaller simple codes and classes though.

Ill try to pull a couple codes out and see if people can help me with them..

Ill just start off with one function...and maybe it will help me with the others..

 // fills one CInventory item from i.e. invent.dat
	friend istream& operator>>(istream& input, const CInventory &item)
	  {
	  operator>>(input, (CInventory &)item);
	  }


I dont really understand whats going on with this code...what is friend...istream...whats the operator tag and what does >> do for it? Is it sending input into CInventory Item? lol...thanks for any help. What topic(s) should I study to understand this better?
Was This Post Helpful? 0
  • +
  • -

#6 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,341
  • Joined: 20-August 07

Re: Trying to learn from code, need help

Posted 02 February 2010 - 04:47 AM

C++ lets you define behaviour for your own operators. There are examples of this in the standard library, where you can use idiomatic syntax to express certain operations; e.g. you can "add" two strings together using the + symbol
#include <string>
#include <iostream>

int main()
{
    std::string a = "hello";
    std::string b = " world";
    std::string c = a + b;

    std::cout << c << std::endl;    
} 
output: hello world

The << operator is also overloaded for strings when used with cout; whose type is std::istream.


You might want to write your own class/struct which you can pass to cout like this
struct person
{
    string first, last;
};

int main()
{
    person p;
    p.first = "joe";
    p.last = "bloggs";

    cout << p << endl;  //ERROR!
} 
to make that code work, you can overload an operator, treating it like a function using the operator keyword, e.g.

std::ostream& operator<<(std::ostream& out, const person& p)
{
    out << p.first << ' ' << p.last;
    return out;
} 
Now its acceptable to use that overloaded operator with a person object alongside cout.


the friend keyword allows an external class or function to access private members of a class. this keyword is typically associated with the << and >> operators because stream operations which work idiomatically with cin/cout must be implemented as external functions - their left-hand argument must be a stream reference. (other operators are perfectly fine to be declared as part of a class/struct however).

This post has been edited by Bench: 02 February 2010 - 05:02 AM

Was This Post Helpful? 0
  • +
  • -

#7 RLB31384  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 97
  • Joined: 29-January 10

Re: Trying to learn from code, need help

Posted 02 February 2010 - 10:01 AM

Thanks Bench,

I actually figured out what Friend did last night but I couldnt update the post. I didn't realize that the other line was an overloaded function.
I have learned about them but haven't really used them much.

My last question...atleast for now..is about moving the functions to the class spec file. Does everyone else declare them in the header file and then write the functions
in the spec file? I can't seem to get them to move over to it. I copied all the functions over and then copied the function headings over and declared them in the header.
I then had to remove all the statics and friends from the spec file..but then..for the overloaded function below..it failed to compile and said this function needed a return value. Should I leave the overloads in the header? Or how can I write them?

// fills one CInventory item from i.e. invent.dat
        friend istream& operator>>(istream& input, const CInventory &item)
          {
          operator>>(input, (CInventory &)item);
          }




heres what I had in the header, friend istream& operator>>(istream& input, const CInventory &item);
and heres what I had in the spec file istream& operator>>(istream& input, const CInventory &item) followed by the rest of the function.

I included the header at the top of the file, but im not sure why it wants a return value now and it didn't before? Im guessing I should just leave those in the
header? Do you guys recommend just leaving all the functions in the header or having them in a spec file. They taught in class to put them in the spec file and just declare the class in the header.

Thanks again
Was This Post Helpful? 0
  • +
  • -

#8 Martyn.Rae  Icon User is offline

  • The programming dinosaur
  • member icon

Reputation: 540
  • View blog
  • Posts: 1,406
  • Joined: 22-August 09

Re: Trying to learn from code, need help

Posted 02 February 2010 - 10:12 AM

Where you put function code is dependant upon many things. We should not really place code in the header file, as this is often more "public" than the code itself. For example, image Microsoft including half of their code in the windows header files. People would be able to copy it, abuse it etc.

Very small portions of code do and often will be included in header files, particulary code from class functions.

Hope that helps
Was This Post Helpful? 0
  • +
  • -

#9 RLB31384  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 97
  • Joined: 29-January 10

Re: Trying to learn from code, need help

Posted 02 February 2010 - 10:28 AM

View PostMartyn.Rae, on 02 February 2010 - 09:12 AM, said:

Where you put function code is dependant upon many things. We should not really place code in the header file, as this is often more "public" than the code itself. For example, image Microsoft including half of their code in the windows header files. People would be able to copy it, abuse it etc.

Very small portions of code do and often will be included in header files, particulary code from class functions.

Hope that helps


Thanks! Thats what I had figured, so I guess ill attempt to move the functions some more. Do you have any idea why the overloaded function that I am trying to move in my last post would want to return a value after I move it and not compile? It compiles fine before I move it. Maybe theres a different way to move them?
Was This Post Helpful? 0
  • +
  • -

#10 Martyn.Rae  Icon User is offline

  • The programming dinosaur
  • member icon

Reputation: 540
  • View blog
  • Posts: 1,406
  • Joined: 22-August 09

Re: Trying to learn from code, need help

Posted 02 February 2010 - 10:40 AM

What you need to do is this.
// fills one CInventory item from i.e. invent.dat
        friend istream& operator>>(istream& input, const CInventory &item);          



then in the code file
        friend istream& operator>>(istream& input, const CInventory &item)          
        {          
             operator>>(input, (CInventory &)item);          
        }



I haven't checked this out for compilation errors. If you get an error is probably due to the friend statement in which case

        istream& operator>>(istream& input, const CInventory &item)          
        {          
             operator>>(input, (CInventory &)item);          
        }



should do the trick.

The reason for this is because the first is a method declaration in the class for the include file, the second in the code file is the method body.

This post has been edited by Martyn.Rae: 02 February 2010 - 10:41 AM

Was This Post Helpful? 0
  • +
  • -

#11 RLB31384  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 97
  • Joined: 29-January 10

Re: Trying to learn from code, need help

Posted 02 February 2010 - 03:11 PM

Same code I tried earlier...gives this:

Error 18 error C4716: 'operator>>' : must return a value inventory.cpp line 64
Error 19 error C4716: 'operator>>' : must return a value inventory.cpp line 64

Anyone have any idea why? It doesn't give this error if I leave the whole code in the header file... Anyone know a way to fix this?

Thanks

Edit:

I wanted to add that if I put return input; at the bottom of it..it gives a bunch of errors like:

POS.obj : error LNK2005: "public: void __thiscall CInventory::init(void)" (?init@CInventory@@QAEXXZ) already defined in Inventory.obj

This post has been edited by RLB31384: 02 February 2010 - 03:28 PM

Was This Post Helpful? 0
  • +
  • -

#12 RLB31384  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 97
  • Joined: 29-January 10

Re: Trying to learn from code, need help

Posted 02 February 2010 - 05:37 PM

Okay I found the problem...for some reason I always thought you had to include the files in a line...but the main file is suppose to include the header...Does the header automatically know that the implementation file needs to be included as well?
Was This Post Helpful? 0
  • +
  • -

#13 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1086
  • View blog
  • Posts: 4,563
  • Joined: 09-June 09

Re: Trying to learn from code, need help

Posted 02 February 2010 - 06:33 PM

all a friend function does is make the function you declared friends with that class :) lol Its a normal function, you still have to input the handle to the class
but the only difference is that you are allowed access to the private members of that class, since there "friends". They should have is be "best friends" lol

example of friends
#include <iostream>

using namespace std;

class foo
{
private:
	int x, y; //private members (not allowed outside of class)

public:
	//constructor
	foo()
	{
		x=10;
	    y=20;
	}

	friend void display(foo &arg); //this is my "display", hes allowed to see my private parts lol

};

//define your function (you dont need to restablish the "friend" part
void display(foo &arg)
{
	cout<<arg.x<<endl<<arg.y<<endl;
}

int main()
{
	foo bob; //handle to class instance
	
	display(bob);

	cin.ignore();
	cin.get();
	return 0;
}


Was This Post Helpful? 0
  • +
  • -

#14 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Trying to learn from code, need help

Posted 02 February 2010 - 06:51 PM

View PostRLB31384, on 01 February 2010 - 03:17 PM, said:

I got this program code from the net, and im trying to modify it a bit and understand the parts that I haven't learned. ... I have never used vectors so I need to research that, that should help me understand this better. I have also never used sprintf, what does this do? This line confuses me a bit its line 174: sprintf(szItemLine, "%12.12s %3d @ %6.2lf %-2.2s %7.2lf",

What is this line doing...Im guessing I need to research sprintf to understand what the numbers are doing? This line also confuses me, its line 144: friend ostream& operator<<(ostream& o, CInventory &item)

Im not sure at all what this line does at all.. If someone could just explain the more complicated things, that would be great.
Thanks!

Heres the code: ....


You may enjoy C++ programming more ... if you avoid C stuff for now ... and if you work up from basics to advanced ... Take a look here for a tutorial:


http://developers-he...index.php/topic,127.msg229.html#msg229
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1