1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Development C++ - C1004: unexpected end-of-file found

Discussion in 'Software' started by Cabe6403, 1 Jul 2010.

  1. Cabe6403

    Cabe6403 Supreme Commander

    Joined:
    3 Apr 2007
    Posts:
    1,205
    Likes Received:
    44
    Right, so I'm new to C++ and I'm working on a small project but I keep getting this error. I've counted all my {},[],'',"" etc but I can't get it fixed =/ :wallbash:

    Until recently I'd basically never used C++. I have some experience in C but mainly in C# and Java. It's probably something ridiculously simply that I'm just missing

    The offending code:

    Code:
    class Attribute {
    
    	Attribute(char sName[], double dValue){
    		char name[] = sName;
    		double value = dValue;
    	}
    
    	void setName(char sName[]){
    		name = sName;
    	}
    
    	char* getName(){
    		return name;
    	}
    
    	void setValue(double dValue){
    		value = dValue;
    	}
    
    	double getValue(){
    		return value;
    	}
    }
    
     
  2. capnPedro

    capnPedro Hacker. Maker. Engineer.

    Joined:
    11 Apr 2007
    Posts:
    4,381
    Likes Received:
    241
    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Attribute {
    	double value;
    	string name;
    
     public:
    	Attribute(string, double);
    	void setValue(double);
    	double getValue();
    
    	void setName(string);
    	string getName();
    };
    
    	 Attribute::Attribute(string sName, double dValue) {
    		name = sName;
    		value = dValue;
    	}
    
    	void Attribute::setName(string sName) {
    		name = sName;
    	}
    
    	string Attribute::getName() {
    		return name;
    	}
    
    	void Attribute::setValue(double dValue) {
    		value = dValue;
    	}
    
    	double Attribute::getValue() {
    		return value;
    	}
    I fixed a few problems. You need to read up how to do classes. And I swapped your character arrays for strings purely because I don't know your data requirements (and strings don't require lengths/recasting) so it would compile OK.
     
    Cabe6403 likes this.
  3. Cabe6403

    Cabe6403 Supreme Commander

    Joined:
    3 Apr 2007
    Posts:
    1,205
    Likes Received:
    44
    Cheers dude, classes in C++ are quite different from what I'm used to!

    rep++;
     
  4. azrael-

    azrael- I'm special...

    Joined:
    18 May 2008
    Posts:
    3,852
    Likes Received:
    124
    Might I suggest not using "using namespace std;". Usually, namespaces are more bother than they're worth and even if not, it's not that hard prefixing STL classes with std::.

    Also, I suggest using "const std::string&" in set functions, e.g. "void Attribute::setName(const string& sName)". Less copying this way.
     
  5. Cabe6403

    Cabe6403 Supreme Commander

    Joined:
    3 Apr 2007
    Posts:
    1,205
    Likes Received:
    44
    Ok, so moving on from that issue. If I want to be able to create and add instances of attribute to a list I'd assume something like this:

    Code:
    vector<Attribute> ATTLIST;
    Attribute C = new Attribute("name",0.123);
    ATTLIST.push_back(C);
    But this doesn't seem to work. I just get that attribute is an unknown identifier.

    I tried cutting and pasting the following into 'Attribute.h' and including that in 'Attribute.cpp' and main but that just threw up a whole bundle of errors.

    Code:
    class Attribute {
    
    	//local variables
    	double value;
    	string name;
    
     public:
    	Attribute(const string&, double);
    	void setValue(double);
    	double getValue();
    
    	void setName(const string&);
    	string getName();
    };
     
  6. azrael-

    azrael- I'm special...

    Joined:
    18 May 2008
    Posts:
    3,852
    Likes Received:
    124
    First off, you need to decide if you want to store objects directly or as pointers in your vector. If you decide to use pointers your code would look something like this:

    Code:
    std::vector<Attribute*> ATTLIST;
    Attribute *obj = new Attribute("name",0.123);
    ATTLIST.push_back(obj);
    
    The upside to using pointers is that, in case of inserting into the vector, no copying will be done. The downside is that you will have to clean up the contents of the vector yourself. There is NO garbage collection in C++!

    Code:
    // cleanup
    for (std::vector<Attribute*>::const_iterator it = ATTLIST.begin(); it != ATTLIST.end(); ++it)
      delete (*it); // deletes current object
    
    ATTLIST.clear(); // removes the (now invalid) pointers from the vector
    
    Alternatively, you can insert "by value", which will copy objects (bad idea for complex types/classes).
    Code:
    std::vector<Attribute> ATTLIST;
    ATTLIST.push_back(Attribute("name",0.123));
    
    This will create an object for "Attribute("name",0.123)" and then another copy of the object when calling push_back(). Also, manipulation of the vector will be quite slow, because it now contains objects, which need to be moved/copied everytime you insert or delete objects.

    The upside, no cleanup necessary.
     
    Last edited: 1 Jul 2010
    Cabe6403 likes this.
  7. capnPedro

    capnPedro Hacker. Maker. Engineer.

    Joined:
    11 Apr 2007
    Posts:
    4,381
    Likes Received:
    241
    You use the new keyword when you want to use a defualt constructor, so Attribute C = new Attribute("name",0.123); should be
    Code:
    Attribute C = Attribute("name",0.123);
    Edit: too slow.

    What sort of errors are you getting when you move stuff to a .h file? Problems with dependencies? Or is it because you've not set a namespace for standard template objects in the header file?
     
    Last edited: 1 Jul 2010
  8. Cabe6403

    Cabe6403 Supreme Commander

    Joined:
    3 Apr 2007
    Posts:
    1,205
    Likes Received:
    44
    Cheers for that Azrael.

    CapnPedro: Compiles fine then make the switch and I get
    Code:
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(5) : error C2146: syntax error : missing ';' before identifier 'name'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(5) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(5) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(8) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(8) : error C2143: syntax error : missing ',' before '&'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(12) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(12) : error C2143: syntax error : missing ',' before '&'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(13) : error C2146: syntax error : missing ';' before identifier 'getName'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(13) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(13) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(13) : warning C4183: 'getName': missing return type; assumed to be a member function returning 'int'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.cpp(12) : error C2511: 'Attribute::Attribute(const std::string &,double)' : overloaded member function not found in 'Attribute'
    1>        c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(1) : see declaration of 'Attribute'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.cpp(18) : error C2511: 'void Attribute::setName(const std::string &)' : overloaded member function not found in 'Attribute'
    1>        c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(1) : see declaration of 'Attribute'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.cpp(22) : error C2556: 'std::string Attribute::getName(void)' : overloaded function differs only by return type from 'int Attribute::getName(void)'
    1>        c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(13) : see declaration of 'Attribute::getName'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.cpp(22) : error C2371: 'Attribute::getName' : redefinition; different basic types
    1>        c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(13) : see declaration of 'Attribute::getName'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.cpp(23) : error C2065: 'name' : undeclared identifier
    Edit:

    I tried the method you wrote Azrael and got this
    Code:
    #include <iostream>
    #include <windows.h>
    #include <vector>
    using namespace std;
    
    void main() {
    	cout << "hello" << endl;
    	Sleep(2000);
    
    
    	std::vector<Attribute> ATTLIST;
    	ATTLIST.push_back(Attribute("name",0.123));
    
    	//Attribute C = new Attribute("name",0.123);
    	//ATTLIST.push_back(C);
    }
    
    giving this:

    Code:
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\main.cpp(11) : error C2065: 'Attribute' : undeclared identifier
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\main.cpp(11) : error C2133: 'ATTLIST' : unknown size
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\main.cpp(11) : error C2512: 'std::vector' : no appropriate default constructor available
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\main.cpp(12) : error C3861: 'Attribute': identifier not found
    I'm going to be offline in about 10 minute and wont be able to get back on until tomorrow. Until then, thanks for the help. I love bit-tech :)
     
    Last edited: 1 Jul 2010
  9. capnPedro

    capnPedro Hacker. Maker. Engineer.

    Joined:
    11 Apr 2007
    Posts:
    4,381
    Likes Received:
    241
    Your first set of errors is because you haven't specified a namespace in your header file.

    In your last section of code, you aren't including Attribute.h
     
  10. azrael-

    azrael- I'm special...

    Joined:
    18 May 2008
    Posts:
    3,852
    Likes Received:
    124
    capnPedro pretty much said it all. Just to add that you don't need the line "using namespace std;" if you prefix std:: before any STL class declaration.

    If there's anything else you need/want to know, just ask... :)
     
  11. capnPedro

    capnPedro Hacker. Maker. Engineer.

    Joined:
    11 Apr 2007
    Posts:
    4,381
    Likes Received:
    241
    Not to hijack the thread (too much), but azrael, could you please explain why setting a namespace is bad? I'm having trouble imagining what sort of trouble it could cause.

    I taught myself to program, so I'm not really very knowledgeable about good practices...
     
  12. azrael-

    azrael- I'm special...

    Joined:
    18 May 2008
    Posts:
    3,852
    Likes Received:
    124
    Namespaces aren't as such a bad thing. Otherwise they wouldn't be part of the language. It's more of a question of using them correctly. And I'm not against using namespaces; I'm against using "using namespace". :)

    Many people use the "using namespace" terminology to avoid having to prefix the namespace before using a type/class within that namespace, i.e. "to have to type less". That's actually the exact opposite of what namespaces are for. Namespaces are meant to make distinctions between types in different contexts.

    An example could be the type/class "string". Let's say you have another implementation of "string" with more or less the same arguments as std::string, but in namespace "myspace::". Now, you include both the std:: and the myspace:: namespaces using "using namespace".

    If you then write e.g. string str = "blah" the compiler will become confused as to which type of string you actually intended to use. However, if you prefix the type with the intended namespace the compiler has no such problems. You, as the developer, on other hand are not limited to make distinctions between your classes by calling them different names. Just use a different namespace.

    Another issue is that you "drag in" every type/class using the aforementioned namespace. That's typically not what you want.

    So, in essence, namespaces are good and "using namespace" is bad. At least in my book. You might want to have a look here to see that my opinion is shared by others.
     
  13. Krikkit

    Krikkit All glory to the hypnotoad! Super Moderator

    Joined:
    21 Jan 2003
    Posts:
    23,926
    Likes Received:
    655
    I think it depends on the complexity of the program, but I have to agree with you there azrael. :)
     
  14. JazzXP

    JazzXP Eh! Steve

    Joined:
    30 Apr 2002
    Posts:
    1,669
    Likes Received:
    13
    For simple classes(ie. not using different namespaces) , 'using namespace' is ok in the cpp file IMO, just keep it out of the headers.
     
  15. Cabe6403

    Cabe6403 Supreme Commander

    Joined:
    3 Apr 2007
    Posts:
    1,205
    Likes Received:
    44
    Right, I think I follow you guys with namespaces but how would I removed the 'using namespace' from this header:

    Code:
    using namespace std;
    
    //Attributes are in the form <name>=<value>
    class Attribute {
    
    	//local variables
    	double value;
    	string name;
    
     public:
    	Attribute(const string&, double);
    	void setValue(double);
    	double getValue();
    
    	void setName(const string&);
    	string getName();
    };
    
     
  16. azrael-

    azrael- I'm special...

    Joined:
    18 May 2008
    Posts:
    3,852
    Likes Received:
    124
    Remove the line "using namespace std;" and change every occurrence of "string" into "std::string".
     
  17. Cabe6403

    Cabe6403 Supreme Commander

    Joined:
    3 Apr 2007
    Posts:
    1,205
    Likes Received:
    44
    Aah, magic. C++ is quite a lot different than I'm used to.

    Last question: I tried googling for it but either I'm searching for the wrong thing or my google-fu is weak today.

    I have another class, Element. Elements are made up off attributes. The class works perfectly fine but when I try make a header file and move the top bit over (this bit)

    Code:
    class Element {
    	int numberOfAttributes;
    	static const int MAX_NUMBER_OF_ATTRIBUTES = 32;
    	std::string name;
    	std::vector<Attribute> ATTLIST;
    
    public:
    	Element(std::string);
    	void setName(const std::string&);
    	std::string getName();
    	int getNumberOfAttributes();
    	void addAttribute(Attribute);
    	Attribute getAttribute(int);
    };
    I get errors about it not knowing what attribute is. I've tried changing Attribute to Attribute::Attribute, Element::Attribute but no luck.
    I even tried #including "Attribute.h" in "Element.h" but that gives me another set off errors and something tells me it isn't the best way to go around it.
     
  18. azrael-

    azrael- I'm special...

    Joined:
    18 May 2008
    Posts:
    3,852
    Likes Received:
    124
    You *do* need to include the header "Attribute.h" in your "Elements.h" file, since you're going to use the type in it.

    I've also made your "get" functions const. You should always make as many of your functions const as possible, especially "get" functions. For "set" functions it's usually best to have const arguments (e.g. const std::string&), unless it cannot be helped.

    Code:
    #include "Attribute.h"
    
    class Element {
    public:
    	Element(const std::string&);
    	void setName(const std::string&);
    	std::string getName() const;
    	int getNumberOfAttributes() const;
    	void addAttribute(Attribute);
    	Attribute getAttribute(int) const;
    
    private:
    	int numberOfAttributes;
    	static const int MAX_NUMBER_OF_ATTRIBUTES;
    	std::string name;
    	std::vector<Attribute> ATTLIST;
    };
    In your Element.cpp file you need to have this (you cannot initialize anything in a class declaration):
    Code:
    const int Element::MAX_NUMBER_OF_ATTRIBUTES = 32;
    Remember to also apply my suggested changes to your class definition (i.e. the function implementations).

    Let me know which errors you get after this.
     
    Cabe6403 likes this.
  19. Cabe6403

    Cabe6403 Supreme Commander

    Joined:
    3 Apr 2007
    Posts:
    1,205
    Likes Received:
    44
    The errors I get now are:

    Code:
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(2) : error C2011: 'Attribute' : 'class' type redefinition
    1>        c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(2) : see declaration of 'Attribute'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\element.cpp(37) : error C2027: use of undefined type 'Attribute'
    1>        c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\attribute.h(2) : see declaration of 'Attribute'
    1>c:\documents and settings\mccabe_s\my documents\visual studio 2008\projects\script\element.cpp(37) : fatal error C1903: unable to recover from previous error(s);
    For reference:
    Element.h
    Code:
    #include "Attribute.h"
    
    class Element {
    public:
    	Element(const std::string&);
    	void setName(const std::string&);
    	std::string getName() const;
    	int getNumberOfAttributes() const;
    	void addAttribute(Attribute);
    	Attribute getAttribute(int) const;
    
    private:
    	int numberOfAttributes;
    	static const int MAX_NUMBER_OF_ATTRIBUTES;
    	std::string name;
    	std::vector<Attribute> ATTLIST;
    };
    Element.cpp
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include "Element.h"
    #include "Attribute.h"
     
    //Elements are made up of attributes. However an element
    //can contain no attributes.
    const int Element::MAX_NUMBER_OF_ATTRIBUTES = 32;
    
    //contstructor: empty element is created
    //name must be provided for identification
    Element::Element(const std::string& sName){
    
    	name = sName;
    	numberOfAttributes = 0;
    }
    
    //Set name for current element
    void Element::setName(const std::string& sName){
    	name = sName;
    }
    
    //returns the name of the current element
    std::string Element::getName() const{
    	return name;
    }
    
    //returns number of attributes in the
    //current element
    int Element::getNumberOfAttributes() const{
    	return numberOfAttributes;
    }
    
    //Allows additional attributes to be added
    //to the current element
    void Element::addAttribute(Attribute aIn){
    	//checks if there is room in this element
    	//for an additional attribute
    	if (numberOfAttributes < MAX_NUMBER_OF_ATTRIBUTES)
    	{
    		ATTLIST.push_back(aIn);
    		numberOfAttributes++;
    		return;
    	}
    	//Error: Max number of attributes reached
    }
    
    //Returns the requested attribute
    Attribute Element::getAttribute(int iAttribute) const{
    	//Checks to ensure a valid request
    	if (iAttribute > numberOfAttributes)
    	{
    		//Error: Out of range
    		return Attribute("ERROR",0.0);
    	}
    	return ATTLIST.at(iAttribute);
    }
    
     
  20. azrael-

    azrael- I'm special...

    Joined:
    18 May 2008
    Posts:
    3,852
    Likes Received:
    124
    For starters remove the line #include "Attribute.h" from Elements.cpp(!). You already include it in the header. Also, all your headers should have a socalled include guard. At the top of every header write something like:
    Code:
    #ifndef ATTRIBUTE_H 
    #define ATTRIBUTE_H
    These should be the first lines in any header you create! Typically you use the header filename in uppercase with an underscore replacing the dot. And also, remember to put and #endif as the very last line of the header.
     

Share This Page