C2146 Error in C++ problem

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 1056 Views - Last Post: 11 June 2012 - 08:41 AM Rate Topic: -----

#1 boris90  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 62
  • Joined: 15-November 09

C2146 Error in C++ problem

Posted 09 June 2012 - 02:00 PM

Hi,

I'd really appreciate some help with his code. I'm making a pharmacy management program. When I run my code, I get the following error log:

1>------ Build started: Project: IT320 Pharmacy, Configuration: Debug Win32 ------
1>Build started 09-Jun-12 22:38:50.
1>InitializeBuildStatus:
1>  Touching "Debug\IT320 Pharmacy.unsuccessfulbuild".
1>ClCompile:
1>  Main.cpp
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(12): error C2146: syntax error : missing ';' before identifier 'lek1'
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(35): error C2065: 'lek1' : undeclared identifier
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(35): error C2228: left of '.unosDatumaProizvodnje' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(36): error C2065: 'lek1' : undeclared identifier
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(36): error C2228: left of '.starostLeka' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(37): error C2065: 'lek1' : undeclared identifier
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(37): error C2228: left of '.prikazStarostiLeka' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(43): error C2065: 'lek1' : undeclared identifier
1>c:\users\boris\documents\visual studio 2010\projects\it320 pharmacy\it320 pharmacy\program.h(43): error C2228: left of '.unosLeka' must have class/struct/union
1>          type is ''unknown-type''
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.43
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



And I've got the following source files with code.

Main.cpp
#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include "Lek.h"
#include "Login.h"
#include "Program.h"
using namespace std;

Lek lek1;
Login login;
Program program;

/////////////////////////////////////////////////

// Glavna metoda (Program)
int main()
{
	
	lek1.trenutnoVreme();

	program.autentikacija();

	cout << endl;
	
	getch();
	return 0;
}



Lek.h
#pragma once
#include <iostream>
#include <string>
#include <ctime>
#include <fstream>
#include "Program.h"
using namespace std;



// Klasa koja sadrzi informacije o lekovima
class Lek
{
	// Osobine leka
public:
	string naziv;
	double cena;
	string barkod;
	double kolicina;
	Program program;

	int proizvedenGodina, proizvedenMesec, proizvedenDan;
	int sadGodina, sadMesec, sadDan;
	int starostGodina, starostMesec, starostDan;
	
	// Provera da li je godina prestupna
	bool daLiPrestupna(int godina)
	{
		if (godina % 400 == 0)
		{
			return true;
		} 
		else
		{
			if (godina % 100 == 0)
			{
				return false;
			} 
			else
			{
				if (godina % 4 == 0)
				{
					return true;					
				} 
				else
				{
					return false;					
				}
			}
		}
	}

	// Proracun trenutnog datuma
	void trenutnoVreme()
	{
		time_t t = time(0);
		struct tm * sada = localtime(& t);

		sadGodina = (sada->tm_year + 1900);
		sadMesec = (sada->tm_mon + 1);
		sadDan = sada->tm_mday;
	}

	// Proracun starosti leka
	void starostLeka()
	{

		// Definise broj dana u mesecu
		// Februar sadrzi 28 ili 29 dana, zbog toga postoji -1 zbog kasnijeg proracuna
		int mesecDan[12] = {31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

		// Proracun starosti u danima
		// Ako je dan proizvodnje veci od danasnjeg dana, onda smestamo vrednost u 
		// inkrement koja ce biti dodata danasnjem danu. 'int mesecDan[]' pomaze u dobijanju dobrog broja
		int inkrement = 0;
		if (proizvedenDan > sadDan)
		{
			inkrement = mesecDan[proizvedenMesec - 1];
		}
		
		// Provera: da li je mesec februar? Ako jeste, koji je broj dana?
		if (inkrement == -1)
		{
			if (daLiPrestupna(proizvedenGodina))
			{
				inkrement = 29;
			} 
			else
			{
				inkrement = 28;
			}
		}

		// Jednostavna aritmeticka operacija; sada inkrement sadrzi broj koji
		// se dodati proizvedenMesec-u
		if (inkrement != 0)
		{
			starostDan = (sadDan + inkrement) - proizvedenDan;
			inkrement = 1;
		} 
		else
		{
			starostDan = sadDan - proizvedenDan;
		}

		// Proracun starosti u mesecima
		// Ako je danasnji mesec manji od rezultata (mesec proizvodnje + inkrement),
		// onda se dodaje 12 danasnjem mesecu, i 1 godini proizvodnje; u suprotom
		// je samo obicno oduzimanje
		if ((proizvedenMesec + inkrement) > sadMesec)
		{
			starostMesec = (sadMesec + 12) - (proizvedenMesec + inkrement);
			inkrement = 1;
		} 
		else
		{
			starostMesec = (sadMesec) - (proizvedenMesec + inkrement);
			inkrement = 0;
		}

		// Proracun starosti u godinama, sledi jednostavna aritmetika
		starostGodina = sadGodina - (proizvedenGodina + inkrement);
	}

	/////////////////////////////////////////////////
	// Unos datuma proizvodnje leka
	void unosDatumaProizvodnje()
	{
		
		if (cin.fail())
		{
			cin.clear();
			cin.ignore();
		}
		
		cout << "Unesite godinu proizvodnje leka (1900 - 2012):\n";
		cin >> proizvedenGodina;

		if (cin.fail())
		{
			cout << "Greska pri unosu godine! Pokusajte ponovo.";
			getch();
			unosDatumaProizvodnje();
		}
		
		if (proizvedenGodina < 1900 || proizvedenGodina > 2012)
		{
			cout << "Unesena godina nije u ispravnom intervalu. Pokusajte ponovo.\n";
			getch();
			unosDatumaProizvodnje();
		}

		cout << endl;

		mesecProizvodnje:
		cout << "Unesite mesec proizvodnje leka (1 - 12):\n";
		cin >> proizvedenMesec;

		if (cin.fail())
		{
			cout << "Greska pri unosu meseca! Pokusajte ponovo.";
			getch();
			unosDatumaProizvodnje();
		}
		
		if (proizvedenMesec < 1 || proizvedenMesec > 12)
		{
			cout << "Unesen mesec nije u ispravnom intervalu. Pokusajte ponovo.\n";
			getch();
			goto mesecProizvodnje;
		}

		cout << endl;

		danProizvodnje:
		cout << "Unesite dan proizvodnje leka (1 - 31):\n";
		cin >> proizvedenDan;

		if (cin.fail())
		{
			cout << "Greska pri unosu dana! Pokusajte ponovo.";
			getch();
			unosDatumaProizvodnje();
		}

		if (proizvedenDan < 1 || proizvedenDan > 31)
		{
			cout << "Unesen dan nije validan! Pokusajte ponovo!\n";
			getch();
			goto danProizvodnje;
		}
		else
		{
			if (daLiPrestupna(proizvedenGodina) && proizvedenMesec == 2)
			{
				if (proizvedenDan == 30 || proizvedenDan == 31)
				{
					cout << "Unesen dan nije validan! Pokusajte ponovo!\n";
					getch();
					goto danProizvodnje;
				}
			}
			else if (!daLiPrestupna(proizvedenGodina) && proizvedenMesec == 2)
			{
				if (proizvedenDan == 29 || proizvedenDan == 30 || proizvedenDan == 31)
				{
					cout << "Unesen dan nije validan! Pokusajte ponovo!\n";
					getch();
					goto danProizvodnje;
				}
			}

			if (proizvedenMesec == 4 || proizvedenMesec == 6 || proizvedenMesec == 9 || proizvedenMesec == 11)
			{
				if (proizvedenDan == 31)
				{
					cout << "Unesen dan nije validan! Pokusajte ponovo!\n";
					getch();
					goto danProizvodnje;
				}
			}
		}

		cout << endl;
	}

	void prikazStarostiLeka()
	{
		cout << "Lek je proizveden pre:\n";
		cout << starostGodina << " godina, " << starostMesec << " meseci i " << starostDan << " dana.\n";
	}

	// Unos novog leka
	void unosLeka()
	{
		ofstream pisiFajl;
		pisiFajl.open("lekovi.txt");
		cout << endl;

		if (pisiFajl.is_open())	// Da li je fajl otvoren?
		{
			// Upis leka
			cout << "Unesite sifru leka (barkod - 13 cifara):\n";
			cin >> barkod;
			cout << endl;
			if (barkod.length() == 13)
			{
				cout << "Barkod uspesno unet!\n\n";
				getch();
			} 
			else
			{
				cout << "Barkod neuspesno unet. Pokusajte ponovo!\n\n";
				getch();
				system("cls");
				unosLeka();
			}

			cout << "Unesite naziv leka:\n";
			cin >> naziv;
			cout << endl;
			
			cout << "Unesite cenu leka:\n";
			cin >> cena;
			cout << endl;

			while (cena < 0)
			{
				cout << "Cena ne moze biti negativna! Unesite ponovo.\n";
				cin >> cena;
				cout << endl;
				getch();
			}

			cout << endl;

			cout << "Unesite kolicinu leka (br. pakovanja):\n(decimalna vrednost bice zaokruzena na donju celu vrednost)";
			cin >> kolicina;
			cout << endl;

			kolicina = floor(kolicina);

			while (kolicina < 0)
			{
				cout << "Kolicina ne moze biti negativna! Unesite ponovo.\n";
				cin >> cena;
				cout << endl;
				getch();
			}

			cout << endl;

			unosDatumaProizvodnje();

			pisiFajl << barkod << " " << naziv << " " << cena << " " << kolicina;

		} 
		else
		{
			cout << "Fajl nije otvoren! Ponovno pokusavanje...";
			getch();
			unosLeka();
		}

		cout << "Zatvaranje fajla...";
		getch();
		pisiFajl.close();
		program.prikazMenija();
	}
		
	Lek(void)
	{
	}

	virtual ~Lek(void)
	{
	}

};



Program.h
#pragma once
#include <iostream>
#include <conio.h>
#include "Lek.h"
#include "Login.h"
using namespace std;

class Program
{
public:
	char opcija;
	Lek lek1;
	Login login1;

	// Glavni meni aplikacije
	void prikazMenija()
	{
		cout << endl;  
		cout << "Dobrodosli. Odaberite opciju:\n"
			<< "1. Provera starosti leka\n"
			<< "2. Unos novog leka\n"
			<< "3. Brisanje leka\n"
			<< "4. Pregled lekova\n"
			<< "5. Izlaz"
			<< endl << endl;

		cin >> opcija;

		cout << endl;

		switch (opcija)
		{
		case '1':
			system("cls");
			lek1.unosDatumaProizvodnje();
			lek1.starostLeka();
			lek1.prikazStarostiLeka();
			prikazMenija();
			break;

		case '2':
			system("cls");
			lek1.unosLeka();
			getch();
			prikazMenija();
			break;

		case '3':
			//				   lek1.brisanjeLeka();
			cout << "Nije implementirano";
			getch();
			system("cls");
			prikazMenija();
			break;

		case '4':
			//				   lek1.pregledLekova();
			cout << "Nije implementirano";
			getch();
			system("cls");
			prikazMenija();
			break;

		case '5':
			exit(1);
			break;

		default:
			cout << endl;
			system("cls");
			cout << "Uneli ste pogresnu opciju. Pokusajte ponovo!\n";
			cout << endl;
			prikazMenija();
			break;

		}
	}

	/////////////////////////////////////////////////

	// Autentikacija korisnika
	void autentikacija()
	{

		ifstream Passfile("password.txt", ios::in);
		Passfile >> login1.inpass;

		ifstream Userfile("username.txt", ios::in);
		Userfile >> login1.inuser;

		system("cls");

		cout << endl;
		cout << "Username: ";
		cin >> login1.username;

		cout << endl;
		cout << "Password: ";
		cin >> login1.password;

		Userfile.close();
		Passfile.close();

		if (login1.username == login1.inuser && login1.password == login1.inpass)
		{
			// Autentikacija je uspela
			system("cls");
			prikazMenija();
		}
		else
		{
			// Autentikacija nije uspela
			cout << endl;
			cout << "Username i/ili sifra nije dobro uneto! Pokusajte ponovo!\n\n";
			getch();
			autentikacija();
		}
	}

	Program(void)
	{
	}

	~Program(void)
	{
	}
};



I think I understand the log a bit, that being that the compiler tells me that it cannot find a ; sign at a specified line. But I don't seem to see where the problem is. Even worse, I think this code worked perfectly before.

If you want to test the app out, you also need a username.txt and password.txt files where your source files are, with 1 username and 1 password in those files, respectively.

Does anyone seem to know where the problem could be?

Thanks in advance.

Is This A Good Question/Topic? 0
  • +

Replies To: C2146 Error in C++ problem

#2 nuclearfroggy  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 82
  • View blog
  • Posts: 167
  • Joined: 04-August 08

Re: C2146 Error in C++ problem

Posted 09 June 2012 - 03:11 PM

Hey, you seem to have missed out one of the files, Login.h I think. Anyways, I can see one major issue. I'm not really sure what Lek should mean :P but in the "Lek" class you have a "Program" object, and in the "Program" class you have a "Lek" object! Thinking about it was kind of like Inception but with classes, anyway, here you need to rethink the structure of your class. Not sure if this makes complete sense but ask if it doesn't :)

Also, I'd recommend against using <conio.h>, (old and nonstandard) and also for the C standard libraries instead of say <stdio.h>, drop the h and put a c infront of it e.g. <cstdio> (the old version's deprecated now).
Was This Post Helpful? 2
  • +
  • -

#3 boris90  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 62
  • Joined: 15-November 09

Re: C2146 Error in C++ problem

Posted 09 June 2012 - 03:48 PM

View Postnuclearfroggy, on 09 June 2012 - 11:11 PM, said:

Hey, you seem to have missed out one of the files, Login.h I think. Anyways, I can see one major issue. I'm not really sure what Lek should mean :P but in the "Lek" class you have a "Program" object, and in the "Program" class you have a "Lek" object! Thinking about it was kind of like Inception but with classes, anyway, here you need to rethink the structure of your class. Not sure if this makes complete sense but ask if it doesn't :)

Also, I'd recommend against using <conio.h>, (old and nonstandard) and also for the C standard libraries instead of say <stdio.h>, drop the h and put a c infront of it e.g. <cstdio> (the old version's deprecated now).


Thanks for the reply. So, here's the Login.h file, though it's of no much significance, I think.

Login.h
#pragma once
#include <iostream>
#include <conio.h>
#include <fstream>
#include <string>
#include <iosfwd>
using namespace std;

class Login
{

public:
	string username, password;
	string inuser, inpass;


};



"Lek" also means "Medicine" in Serbian, not as a science, but rather as some kind of cure. You could call it "Cure", it's more understandable. Any other ideas how I could solve this?
Was This Post Helpful? 0
  • +
  • -

#4 boris90  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 62
  • Joined: 15-November 09

Re: C2146 Error in C++ problem

Posted 09 June 2012 - 03:55 PM

View Postnuclearfroggy, on 09 June 2012 - 11:11 PM, said:

Hey, you seem to have missed out one of the files, Login.h I think. Anyways, I can see one major issue. I'm not really sure what Lek should mean :P but in the "Lek" class you have a "Program" object, and in the "Program" class you have a "Lek" object! Thinking about it was kind of like Inception but with classes, anyway, here you need to rethink the structure of your class. Not sure if this makes complete sense but ask if it doesn't :)

Also, I'd recommend against using <conio.h>, (old and nonstandard) and also for the C standard libraries instead of say <stdio.h>, drop the h and put a c infront of it e.g. <cstdio> (the old version's deprecated now).


And yeah, about the class object thingies: I really need the objects in those classes, need them for certain operations and tasks. No other solution than this comes to mind. Maybe if I could create some other class and cut-and-paste the methods there (and call the methods from there)?

Tell me if you think this could solve the problem. I'm going to continue thinking about this more deeply tomorrow, 'cause it's 00:55 right now here, and I'm all sleepy. :sleep1:

Anyway, if you think putting the methods in another class would solve it, tell me so I could try that tomorrow. Or perhaps tell me what other stuff to try, so I'll reply again tomorrow.

Thanks, buddy!

This post has been edited by boris90: 09 June 2012 - 03:56 PM

Was This Post Helpful? 0
  • +
  • -

#5 Oler1s  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1395
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: C2146 Error in C++ problem

Posted 09 June 2012 - 04:37 PM

Please step back and think about what are you designing:

class Lek
{
    ....
    Program program;
}


So a Lek contains a Program.

class Program
{
    ...
    Lek lek1;
}



but a Program must contain a Lek?

How can this work?
Was This Post Helpful? 3
  • +
  • -

#6 boris90  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 62
  • Joined: 15-November 09

Re: C2146 Error in C++ problem

Posted 10 June 2012 - 03:16 AM

View PostOler1s, on 10 June 2012 - 12:37 AM, said:

Please step back and think about what are you designing:

class Lek
{
    ....
    Program program;
}


So a Lek contains a Program.

class Program
{
    ...
    Lek lek1;
}



but a Program must contain a Lek?

How can this work?


Well, practically, yeah, that's what I need within my application. Now I have to find a way to implement this differently. I'll keep trying and if someone comes up with an idea, please post here. As I mentioned before, maybe I could cut my application's code into several pieces and separate them in a couple more classes. I'll try to invent a new scheme here.
Was This Post Helpful? 0
  • +
  • -

#7 nuclearfroggy  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 82
  • View blog
  • Posts: 167
  • Joined: 04-August 08

Re: C2146 Error in C++ problem

Posted 10 June 2012 - 04:22 AM

I can kind of see where you're coming from, could you fill me in on what you want the various classes? It makes sense why the Program class would need a Lek (cure?) object. I'm assuming the Program class more like a general class that holds all the stuff for when you run your pharmacy program, and has member functions that get input from the user etc.

However, the "Lek" class seems to me like it shouldn't need to be dependent on the "Program" class. Could you explain the functionility of this class and why it needs a Program object? You only make 1 reference to the Program object in the entire Lek class, which hints to me a bit of rethinking could eliminate this.

The only possible situation I can think of is the cure needs a reference to the program object that stores it. In this case, you would do it by having a "Program" pointer rather than an object. A similar situation I had was when I was writing an airline reservation program, where there were tickets and flights. The flight object class had to hold a set of tickets, but the tickets had to record the flight they referred to. To implement this the solution that seemed natural to me was store the tickets in a structure in the flight class, and then each ticket had a pointer - "flight *curr" which kept a reference to the flight the ticket applied to.

Also another thing that's slightly off-topic, in general, for most class member functions (one's that aren't very short) you should just keep a function prototype in the class definition and then actually implement them in another file, say you'll have "Lek.h" which contains the class definition (headers shouldn't really have code in) and then "Lek.cpp" with the implementation.

Hope this helps, I want to help more but I can't really translate the comments.
Was This Post Helpful? 0
  • +
  • -

#8 boris90  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 62
  • Joined: 15-November 09

Re: C2146 Error in C++ problem

Posted 10 June 2012 - 05:04 AM

View Postnuclearfroggy, on 10 June 2012 - 12:22 PM, said:

I can kind of see where you're coming from, could you fill me in on what you want the various classes? It makes sense why the Program class would need a Lek (cure?) object. I'm assuming the Program class more like a general class that holds all the stuff for when you run your pharmacy program, and has member functions that get input from the user etc.

However, the "Lek" class seems to me like it shouldn't need to be dependent on the "Program" class. Could you explain the functionility of this class and why it needs a Program object? You only make 1 reference to the Program object in the entire Lek class, which hints to me a bit of rethinking could eliminate this.

The only possible situation I can think of is the cure needs a reference to the program object that stores it. In this case, you would do it by having a "Program" pointer rather than an object. A similar situation I had was when I was writing an airline reservation program, where there were tickets and flights. The flight object class had to hold a set of tickets, but the tickets had to record the flight they referred to. To implement this the solution that seemed natural to me was store the tickets in a structure in the flight class, and then each ticket had a pointer - "flight *curr" which kept a reference to the flight the ticket applied to.

Also another thing that's slightly off-topic, in general, for most class member functions (one's that aren't very short) you should just keep a function prototype in the class definition and then actually implement them in another file, say you'll have "Lek.h" which contains the class definition (headers shouldn't really have code in) and then "Lek.cpp" with the implementation.

Hope this helps, I want to help more but I can't really translate the comments.


Yes, the Program class actually has the application's "program" stuff, like the main menu and the user authentication (which is checked from the two corresponding files). Initially, I had these two methods in a Program class implemented in a Main.cpp file, but I didn't know how to call the methods from a .cpp file, which aren't part of any class, but rather defined in a .cpp file. I also read on several forums that forward declarations would be a nice solution for what I have, like some sort of mutual header file inclusion. That's what is suggested by several people on several forums, but I don't know how reliable that is.

So practically, on a global scale:

  • I have a Main.cpp file which holds the main method.
  • The main method calls the authentication and showMenu methods from the Program class / header, which are general application stuff needed for initial interaction with the user.
  • The user enters a certain option number; all the options which are chosen by the user (and all the options are defined in the Program.h because of the main menu) are directly related to the Lek.h file (Lek class), because that's what the whole application is about: the cures (Lek's). That's why the Program class calls lots of methods and variables from the Lek class.
  • As of the Lek.h file, the Lek class that is, you're right. Looks like I only have one reference to the Program.h file (Program class), and that's in the unosLeka() method of the Lek.h file. "Unos Leka" means the "Cure Input", where the user inputs the barcode of the cure, it's name, production date, price etc. After the user enters all the data, these data are written into a text file and after that we have the following part:

    cout << "Zatvaranje fajla...";
    getch();
    pisiFajl.close();
    program.prikazMenija();
    
    


    The user gets the message: "Closing file...", the file input object pisiFajl, or "writeFile" is closed and after the input the showMenu() method from the program is called. I added this because I needed to show the program menu again, after user inputs the cure data and saves it into a text file (of course, he needs to get back to the previous options).


So, what would you suggest?
Was This Post Helpful? 0
  • +
  • -

#9 nuclearfroggy  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 82
  • View blog
  • Posts: 167
  • Joined: 04-August 08

Re: C2146 Error in C++ problem

Posted 10 June 2012 - 05:46 AM

Ah ok, thanks for clarifying. Most likely what you want is to have the Lek class implemented without any Program object at all. The Cure method is called, taking the cure data from the user and writing to a file, but then you want to return back to the program menu. The Lek class doesn't need to be dependent on "Program" at any point.

It seems to me that instead you should have a while loop in Program's menu method that basically loops until the user chooses to quit. This would allow you to call the Lek functions but return back to the menu afterwards ready for more input.
Was This Post Helpful? 0
  • +
  • -

#10 boris90  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 62
  • Joined: 15-November 09

Re: C2146 Error in C++ problem

Posted 10 June 2012 - 10:30 AM

OK, I don't have a problem with the mutual header inclusion anymore; but I seem to have another problem, a problem that I didn't have before! >_<
Namely, within my code, in the Lek.h file and class, I have a trenutnoVreme() method (currentTime()) for calculating the current year, month and day. Now, it used to work perfectly before, I didn't touch anything in that code, and now it returns 10 as a day (which is correct, because it's 10th of June), 6 as a month (correct, because June is a 6th month), and 0 as a year! Previously, it indeed returned 2012, but now it returns 0.
My first thought is that something may be wrong with the order of method calls or the order of method execution. I don't know anymore. Below is my current code (I will not show Login.h because it's irrelevant to this problem):


Needed translations for better understanding (ask if you need more translations, like for comments):

sada, sad = now
dan = day
mesec = month
godina = year


The below are mentioned in the names of variables in the upper parts of code:

proizveden = produced (in the context of variables, indicating when something is produced)
starost = age


Main.cpp
#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include "Lek.h"
#include "Login.h"
#include "Program.h"
using namespace std;

Lek lek1;
Login login;
Program program;

/////////////////////////////////////////////////
// Glavna metoda (Program)
int main()
{
	
	lek1.trenutnoVreme();

	program.autentikacija();

	cout << endl;
	
	getch();
	return 0;
}



Lek.h
#pragma once
#include <iostream>
#include <string>
#include <ctime>
#include <fstream>
#include <dos.h>
using namespace std;



// Klasa koja sadrzi informacije o lekovima
class Lek
{
	// Osobine leka
public:
	string naziv;
	double cena;
	string barkod;
	double kolicina;

	int proizvedenGodina, proizvedenMesec, proizvedenDan;
	int sadGodina, sadMesec, sadDan;
	int starostGodina, starostMesec, starostDan;
	
	// Provera da li je godina prestupna
	bool daLiPrestupna(int godina)
	{
		if (godina % 400 == 0)
		{
			return true;
		} 
		else
		{
			if (godina % 100 == 0)
			{
				return false;
			} 
			else
			{
				if (godina % 4 == 0)
				{
					return true;					
				} 
				else
				{
					return false;					
				}
			}
		}
	}

	// Proracun trenutnog datuma
	void trenutnoVreme()
	{
		time_t t = time(NULL);
		struct tm * sada = localtime(& t);

		sadGodina = (sada->tm_year + 1900);
		sadMesec = (sada->tm_mon + 1);
		sadDan = sada->tm_mday;
	}

	// Proracun starosti leka
	void starostLeka()
	{

		// Definise broj dana u mesecu
		// Februar sadrzi 28 ili 29 dana, zbog toga postoji -1 zbog kasnijeg proracuna
		int mesecDan[12] = {31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

		// Proracun starosti u danima
		// Ako je dan proizvodnje veci od danasnjeg dana, onda smestamo vrednost u 
		// inkrement koja ce biti dodata danasnjem danu. 'int mesecDan[]' pomaze u dobijanju dobrog broja
		int inkrement = 0;
		if (proizvedenDan > sadDan)
		{
			inkrement = mesecDan[proizvedenMesec - 1];
		}
		
		// Provera: da li je mesec februar? Ako jeste, koji je broj dana?
		if (inkrement == -1)
		{
			if (daLiPrestupna(proizvedenGodina))
			{
				inkrement = 29;
			} 
			else
			{
				inkrement = 28;
			}
		}

		// Jednostavna aritmeticka operacija; sada inkrement sadrzi broj koji
		// se dodati proizvedenMesec-u
		if (inkrement != 0)
		{
			starostDan = (sadDan + inkrement) - proizvedenDan;
			inkrement = 1;
		} 
		else
		{
			starostDan = sadDan - proizvedenDan;
		}

		// Proracun starosti u mesecima
		// Ako je danasnji mesec manji od rezultata (mesec proizvodnje + inkrement),
		// onda se dodaje 12 danasnjem mesecu, i 1 godini proizvodnje; u suprotom
		// je samo obicno oduzimanje
		if ((proizvedenMesec + inkrement) > sadMesec)
		{
			starostMesec = (sadMesec + 12) - (proizvedenMesec + inkrement);
			inkrement = 1;
		} 
		else
		{
			starostMesec = (sadMesec) - (proizvedenMesec + inkrement);
			inkrement = 0;
		}

		// Proracun starosti u godinama, sledi jednostavna aritmetika
		starostGodina = sadGodina - (proizvedenGodina + inkrement);
	}

	/////////////////////////////////////////////////
	// Unos datuma proizvodnje leka
	void unosDatumaProizvodnje()
	{
		
		if (cin.fail())
		{
			cin.clear();
			cin.ignore();
		}
		
		cout << "Unesite godinu proizvodnje leka (1900 - 2012):\n";
		cin >> proizvedenGodina;

		if (cin.fail())
		{
			cout << "Greska pri unosu godine! Pokusajte ponovo.";
			getch();
			unosDatumaProizvodnje();
		}
		
		if (proizvedenGodina < 1900 || proizvedenGodina > 2012)
		{
			cout << "Unesena godina nije u ispravnom intervalu. Pokusajte ponovo.\n";
			getch();
			unosDatumaProizvodnje();
		}

		cout << endl;

		mesecProizvodnje:
		cout << "Unesite mesec proizvodnje leka (1 - 12):\n";
		cin >> proizvedenMesec;

		if (cin.fail())
		{
			cout << "Greska pri unosu meseca! Pokusajte ponovo.";
			getch();
			unosDatumaProizvodnje();
		}
		
		if (proizvedenMesec < 1 || proizvedenMesec > 12)
		{
			cout << "Unesen mesec nije u ispravnom intervalu. Pokusajte ponovo.\n";
			getch();
			goto mesecProizvodnje;
		}

		cout << endl;

		danProizvodnje:
		cout << "Unesite dan proizvodnje leka (1 - 31):\n";
		cin >> proizvedenDan;

		if (cin.fail())
		{
			cout << "Greska pri unosu dana! Pokusajte ponovo.";
			getch();
			unosDatumaProizvodnje();
		}

		if (proizvedenDan < 1 || proizvedenDan > 31)
		{
			cout << "Unesen dan nije validan! Pokusajte ponovo!\n";
			getch();
			goto danProizvodnje;
		}
		else if (proizvedenDan >= 1 || proizvedenDan <= 31)
		{
			if (daLiPrestupna(proizvedenGodina) && proizvedenMesec == 2)
			{
				if (proizvedenDan == 30 || proizvedenDan == 31)
				{
					cout << "Unesen dan nije validan! Pokusajte ponovo!\n";
					getch();
					goto danProizvodnje;
				}
			}
			else if (!daLiPrestupna(proizvedenGodina) && proizvedenMesec == 2)
			{
				if (proizvedenDan == 29 || proizvedenDan == 30 || proizvedenDan == 31)
				{
					cout << "Unesen dan nije validan! Pokusajte ponovo!\n";
					getch();
					goto danProizvodnje;
				}
			}

			if (proizvedenMesec == 4 || proizvedenMesec == 6 || proizvedenMesec == 9 || proizvedenMesec == 11)
			{
				if (proizvedenDan == 31)
				{
					cout << "Unesen dan nije validan! Pokusajte ponovo!\n";
					getch();
					goto danProizvodnje;
				}
			}
		}

		cout << endl;
	}

	void prikazStarostiLeka()
	{										  
		cout << "Lek je proizveden pre:\n";
		cout << starostGodina << " godina, " << starostMesec << " meseci i " << starostDan << " dana.\n";
		getch();
		system("cls");
	}

	// Unos novog leka
	void unosLeka()
	{
		ofstream pisiFajl;
		pisiFajl.open("lekovi.txt");
		cout << endl;

		if (pisiFajl.is_open())	// Da li je fajl otvoren?
		{
			// Upis leka
			cout << "Unesite sifru leka (barkod - 13 cifara):\n";
			cin >> barkod;
			cout << endl;
			if (barkod.length() == 13)
			{
				cout << "Barkod uspesno unet!\n\n";
				getch();
			} 
			else
			{
				cout << "Barkod neuspesno unet. Pokusajte ponovo!\n\n";
				getch();
				system("cls");
				unosLeka();
			}

			cout << "Unesite naziv leka:\n";
			cin >> naziv;
			cout << endl;
			
			cout << "Unesite cenu leka:\n";
			cin >> cena;
			cout << endl;

			while (cena < 0)
			{
				cout << "Cena ne moze biti negativna! Unesite ponovo.\n";
				cin >> cena;
				cout << endl;
				getch();
			}

			cout << endl;

			cout << "Unesite kolicinu leka (br. pakovanja):\n(decimalna vrednost bice zaokruzena na donju celu vrednost)";
			cin >> kolicina;
			cout << endl;

			kolicina = floor(kolicina);

			while (kolicina < 0)
			{
				cout << "Kolicina ne moze biti negativna! Unesite ponovo.\n";
				cin >> cena;
				cout << endl;
				getch();
			}

			cout << endl;

			unosDatumaProizvodnje();

			pisiFajl << barkod << " " << naziv << " " << cena << " " << kolicina;

		} 
		else
		{
			cout << "Fajl nije otvoren! Ponovno pokusavanje...";
			getch();
			unosLeka();
		}

		cout << "Zatvaranje fajla...";
		getch();
		pisiFajl.close();
	}
		
	Lek(void)
	{
	}

	virtual ~Lek(void)
	{
	}

};



Program.h
#pragma once
#include <iostream>
#include <conio.h>
#include "Lek.h"
#include "Login.h"
using namespace std;

class Program
{
public:
	char opcija;
	Lek lek1;
	Login login1;

	/////////////////////////////////////////////////

	// Autentikacija korisnika
	void autentikacija()
	{

		ifstream Passfile("password.txt", ios::in);
		Passfile >> login1.inpass;

		ifstream Userfile("username.txt", ios::in);
		Userfile >> login1.inuser;

		system("cls");

		cout << endl;
		cout << "Username: ";
		cin >> login1.username;

		cout << endl;
		cout << "Password: ";
		cin >> login1.password;

		Userfile.close();
		Passfile.close();

		if (login1.username == login1.inuser && login1.password == login1.inpass)
		{
			// Autentikacija je uspela
			system("cls");
			// Meni aplikacije
			do 
			{
				cout << endl;  
				cout << "Dobrodosli. Odaberite opciju:\n"
					<< "1. Provera starosti leka\n"
					<< "2. Unos novog leka\n"
					<< "3. Brisanje leka\n"
					<< "4. Pregled lekova\n"
					<< "5. Izlaz"
					<< endl << endl;

				cin >> opcija;

				cout << endl;

				switch (opcija)
				{
				case '1':
					system("cls");
					lek1.unosDatumaProizvodnje();
					lek1.starostLeka();
					lek1.prikazStarostiLeka();
					break;

				case '2':
					system("cls");
					lek1.unosLeka();
					getch();
					break;

				case '3':
					// lek1.brisanjeLeka();
					cout << "Nije implementirano";
					getch();
					system("cls");
					break;

				case '4':
					// lek1.pregledLekova();
					cout << "Nije implementirano";
					getch();
					system("cls");
					break;

				case '5':
					exit(1);
					break;

				default:
					cout << endl;
					system("cls");
					cout << "Uneli ste pogresnu opciju. Pokusajte ponovo!\n";
					cout << endl;
					break;
				}
			} while (opcija != '5');

		}
		else
		{
			// Autentikacija nije uspela
			cout << endl;
			cout << "Username i/ili sifra nije dobro uneto! Pokusajte ponovo!\n\n";
			getch();
			autentikacija();
		}
	}

	Program(void)
	{
	}

	~Program(void)
	{
	}
};



The app just doesn't seem to be able to return the proper age of a cure. For example, if I entered 1990, 11 and 8 for a year, month and day respectively (for the date when the cure was produced), it would return Lek je proizveden pre -1991 godina, 0 meseci i 22 dana (The cure was produced -1991 years, 0 months and 22 days ago). :helpsmilie:

This post has been edited by boris90: 10 June 2012 - 10:34 AM

Was This Post Helpful? 0
  • +
  • -

#11 nuclearfroggy  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 82
  • View blog
  • Posts: 167
  • Joined: 04-August 08

Re: C2146 Error in C++ problem

Posted 10 June 2012 - 12:12 PM

Right, one of the reason you're now facing problems is you've got lek1 as a global variable and also a member variable in the Program class. At the start of main() you initialise lek1 (global), but then when you call the Program's menu function you're now using a different, uninitialised lek1 object.

First off, you shouldn't use global variables whenever possible. Next if you want to initialise the time you could maybe do this in the constructor of the Program class - the more self contained the better.

A bigger issue seems to be how you've implemented the menu function. Recursion is definitely not the way to go here (recursion is when a function calls itself). This just makes something more confusing than it needs to be, and also, after the user has used your program for a while (without quitting), the stack space will be slowly be used up and this could even end up with the program crashing. All you need is a simple while or do while loop, that terminates only when the user has chosen to quit. Something like:
do // keep the "program" running
{
    // output options like you did before    
    cin >> opcija;
    switch(opcija)
    {
        // code mostly as before
    }
} while(opcija != '5'); // until the user chooses to exit

You won't want to quit the program with exit() either, simply allow the function to finish and exit gracefully :) . Sorry if it seems like I'm trying to pick holes, the more conformant and better structured the code, the less problems you'll get with it!
Was This Post Helpful? 0
  • +
  • -

#12 boris90  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 62
  • Joined: 15-November 09

Re: C2146 Error in C++ problem

Posted 10 June 2012 - 03:25 PM

View Postnuclearfroggy, on 10 June 2012 - 08:12 PM, said:

Right, one of the reason you're now facing problems is you've got lek1 as a global variable and also a member variable in the Program class. At the start of main() you initialise lek1 (global), but then when you call the Program's menu function you're now using a different, uninitialised lek1 object.

First off, you shouldn't use global variables whenever possible. Next if you want to initialise the time you could maybe do this in the constructor of the Program class - the more self contained the better.

A bigger issue seems to be how you've implemented the menu function. Recursion is definitely not the way to go here (recursion is when a function calls itself). This just makes something more confusing than it needs to be, and also, after the user has used your program for a while (without quitting), the stack space will be slowly be used up and this could even end up with the program crashing. All you need is a simple while or do while loop, that terminates only when the user has chosen to quit. Something like:
do // keep the "program" running
{
    // output options like you did before    
    cin >> opcija;
    switch(opcija)
    {
        // code mostly as before
    }
} while(opcija != '5'); // until the user chooses to exit

You won't want to quit the program with exit() either, simply allow the function to finish and exit gracefully :) . Sorry if it seems like I'm trying to pick holes, the more conformant and better structured the code, the less problems you'll get with it!


Hey, thanks for this menu with the do-while loop thingy, but as you may have noticed, I've already done this with the same do-while loop layout you specified above (take a look at the Program.h file). The only problem that remains is the time I mentioned earlier, and I'll try to fix it now by taking your previous advice into consideration (with the global and member variables). I really need to fix the cure age issue ASAP.

This post has been edited by boris90: 10 June 2012 - 03:25 PM

Was This Post Helpful? 0
  • +
  • -

#13 boris90  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 62
  • Joined: 15-November 09

Re: C2146 Error in C++ problem

Posted 10 June 2012 - 03:44 PM

I just tried experimenting with the
Lek lek1
declaration: I cut-and-pasted it (within the Main.cpp file) inside the main() method, and no difference was made. When I declared
Lek lek1
outside the Program class (just above the class Program line), I got an error C2086 'Lek lek1': redefinition. So, looks like no matter where I declare the Lek lek1, the problem still persists.
What were you talking about the time initialization in the constructor? How did you mean I could implement that? I'm not quite familiar with time initialization and constructors (though I'm still working on them :sweatdrop:).

Your help would surely be appreciated! :blush:
Was This Post Helpful? 0
  • +
  • -

#14 nuclearfroggy  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 82
  • View blog
  • Posts: 167
  • Joined: 04-August 08

Re: C2146 Error in C++ problem

Posted 11 June 2012 - 02:16 AM

Sorry about the do while thing, I must have been looking at the old version, ignore me being stupid!

I could fix the problem by removing the global variable lek1 and just leaving having one lek1 in the Program class. Then in the constructor, of the Program class (which is the function Program() ) you could make a call to trenutNoVreme(), like
Program()
{
   lek1.trenutnoVreme();
}

This will initialise it with the correct time. By the way, do you have a decent debugger? Stepping through the program makes it easy to work out the problem.

EDIT: also the reason that you got the error was when you copied "lek1" outside of the class you're now trying to declare the same thing twice - both are global variables. There's no need for another lek object here. Leave the "lek1" inside the class Program and get rid of the "lek1" in main.cpp

This post has been edited by nuclearfroggy: 11 June 2012 - 03:30 AM

Was This Post Helpful? 0
  • +
  • -

#15 boris90  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 62
  • Joined: 15-November 09

Re: C2146 Error in C++ problem

Posted 11 June 2012 - 07:06 AM

View Postnuclearfroggy, on 11 June 2012 - 10:16 AM, said:

Sorry about the do while thing, I must have been looking at the old version, ignore me being stupid!

I could fix the problem by removing the global variable lek1 and just leaving having one lek1 in the Program class. Then in the constructor, of the Program class (which is the function Program() ) you could make a call to trenutNoVreme(), like
Program()
{
   lek1.trenutnoVreme();
}

This will initialise it with the correct time. By the way, do you have a decent debugger? Stepping through the program makes it easy to work out the problem.

EDIT: also the reason that you got the error was when you copied "lek1" outside of the class you're now trying to declare the same thing twice - both are global variables. There's no need for another lek object here. Leave the "lek1" inside the class Program and get rid of the "lek1" in main.cpp


Thanks a million! It worked! :bananaman:
I got rid of the lek1 object in Main.cpp and called the lek1.trenutnoVreme(); function from within the Program.h constructor. The time now shows correctly: 21 years, 7 months and 3 days for the date specified above.

Again, thanks! If anything else goes wrong, I'll either post a new topic or reply here. But I guess there won't be any problems.

This post has been edited by boris90: 11 June 2012 - 07:06 AM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2