Hard Light Productions Forums

Off-Topic Discussion => General Discussion => Topic started by: kasperl on July 31, 2004, 02:31:33 pm

Title: C++ Help.
Post by: kasperl on July 31, 2004, 02:31:33 pm
I need some help. I'm making a mission builder for FSO, so someone can make a mission, edit it to add vars to be randomized, and then toss it through my program to make a complete mission for use in FSO for skirmishes and the like.

This is also my first bit of C++ ever, so naturally I have no idea what the hell is going on.

I get a whole bunch of errors from the compiler (VC6) that I simply can't place, and I need someone who knows his C to help me out. I'm right now stuck at even the most basic things. (A system to check if a message has to be outputted, so I won't have to comment/uncomment messages each time I change something.)

Anyone want to help me?

http://www.sectorgame.com/FSCZ/kasperl/temp/Builder/
That is a dir with all the files from the 'project'.

EDIT:

the most recent upload, works without issues, thanks.
http://www.sectorgame.com/FSCZ/kasperl/temp/builder3.rar/
Title: C++ Help.
Post by: jdjtcagle on July 31, 2004, 02:39:24 pm
Iiinteerreessstiiing...
Good luck :)
Title: C++ Help.
Post by: kasperl on July 31, 2004, 02:40:00 pm
Yeah, well, it won't even compile right now.
Title: C++ Help.
Post by: ChronoReverse on July 31, 2004, 03:05:36 pm
Well, I've found a gazillion spelling errors and a few cases of incorrect usage of classes and often-times the () isn't placed after a function call (which also means I have no idea what's supposed to go into the braces).

Oh and use #include < iostream > instead of #include < iosteam.h >

And I'm not sure, but I don't think it's a good idea to call global functions from within a class.


Code: [Select]
int MLevel2 = MLevel1::GetMLevel();

Considering that MLevel1 is the name of your class, this isn't going to work.  You need to work with an instance of the class.

Code: [Select]
if(Level < MLevel1)

Likewise here.
Title: C++ Help.
Post by: WMCoolmon on July 31, 2004, 03:51:49 pm
In mlevel.h, getmlevel needs to return some sort of value (void or otherwise) - it returns an int in the CPP

It's also probably a good idea to put private things first, since classes are by default private; the way you have it is the reverse of the way it's coded in any other program.

Why is Mlevel numbered? It only declares a class type, not an instance, to do that you need to use
Code: [Select]
Mlevel Mlevel1;
or declare the name after the } and before the ; in the class definition.

When you're checking for a null pointer, if(pFirst == 0) should be if(pFilrst == NULL), it is considered bad practice to assume null pointers are 0; although they are on Win32 and Linux, I believe.

You can only have one linked list class instance in your entire program, though. All the items will be added to one big list because of the *pFirst pointer being static.

You should probably just use vectors, a linked list just adds complexity for speed, and speed isn't going to be a factor here since it's an external program / utility instead of an actual gameplay element.

A final word, you should probably make it possible to call the main mission-generating function from outside the program, so that it could be used as a plugin to FRED or something.

Edit: Oh yeah, don't ever name functions the same as pointers. It'll confuse the compiler because it won't be able to tell if you're talking about the variable with that name or trying to use a pointer to the function.
Title: C++ Help.
Post by: aldo_14 on July 31, 2004, 07:47:35 pm
This might be of use;
http://www.cplusplus.com/doc/tutorial/index.html

(I started working through this a few months ago, up till the point I actually started work and thus ran out of time - I found it pretty useful)
Title: C++ Help.
Post by: jdjtcagle on July 31, 2004, 07:54:41 pm
I started a mission, what all does it need exactly?
It's halfway there and doesn't require mods
Title: C++ Help.
Post by: vyper on July 31, 2004, 07:57:08 pm
Working code.

Seriously, give him some time to get this perfected or you may end up having to rewrite parts of the said mission. :) Take it from one who knows, you go through several iterations of most small applications during development, all handling the problem in a slightly different/better way.
Title: C++ Help.
Post by: kasperl on August 01, 2004, 03:44:38 am
Thanks for all the help, I'll try to start fixing things.

And remaining some stuff.
Title: C++ Help.
Post by: kasperl on August 01, 2004, 04:46:07 am
Oh yes, jdj, vyper is right. Black Wolf is right now the only one who wrote for this, and with reason. Right now, I changed the way I want the files about 3 times, and I haven't even started writing any usefull code yet. Wait untill there is at least some documentation.
Title: C++ Help.
Post by: kasperl on August 01, 2004, 04:58:21 am
This is more frustrating then I thought.....

I started over, because it was such a mess more edits would only make it worse. I thought it would be better to make a Message class, and define the current level as a static int. Now, in theory, this is good, right? The constructor of a new message will output the message, so you'll only need to make a new message type variable, and make sure it get's killed. Not that hard, right?

Well, it won't even compile. Mind you, it's only one error now, instead of 44 the last time. And I've managed to keep all the stuff in one file, instead of 10. I'll upload the code in a moment, but I just can't figure out why it won't compile. It complains about the static int, this error:

main.obj : error LNK2001: unresolved external symbol "private: static int  Message::SendLevel" (?SendLevel@Message@@0HA)
Debug/Builder2.exe : fatal error LNK1120: 1 unresolved externals


edit:
www.sectorgame.com/FSCZ/kasperl/temp/Builder2/
Title: C++ Help.
Post by: WMCoolmon on August 01, 2004, 05:08:19 am
IIRC, static has a different meaning in classes - it is the same for all instances of that class.
Title: C++ Help.
Post by: kasperl on August 01, 2004, 05:09:29 am
That's exactly what I wanted. I want that var to be the same for all the intances. The problem is, I nearly copied the code from C++ for Dummies, only changing names and stuff, but it won't compile.
Title: C++ Help.
Post by: WMCoolmon on August 01, 2004, 05:18:56 am
Well, you never set the value for it, that could be a problem...

I think you're 'focusing on object-oriented code too much. This is much simpler, and will run faster:

Code: [Select]
//This is a global
const int OuputLevel = 50;

//Later on
void OutputMessage(char* MessageText, int Level = 90)
{
     if(Level >= OutputLevel)
          cout << MessageText;
}


Id recommend making it possible to easily output variables - this would force you to learn more about creating custom IOStreams though, or require you to use C functions for text-based output.

Also before implementing messages for constructors/destructors, at least glance through how VCs debugger runs. It takes a little learning but can be very very useful. Outputting every construction/destruction will likely just slow your program down and make it impossible to tell what happens when you output them.
Title: C++ Help.
Post by: kasperl on August 01, 2004, 05:20:15 am
I'd rather not start playing around with the iostreams just yet, but I'll just dump the whole object approach.
Title: C++ Help.
Post by: WMCoolmon on August 01, 2004, 05:36:39 am
add
Code: [Select]
<< endl;

onto thwe wend so wecwerything isnt writtwen to thwe samwe linwe.

Dammit, that watwer
i spil
l

wed on my kweyboard rweally did short circuit it. :p
Title: C++ Help.
Post by: kasperl on August 01, 2004, 05:59:54 am
Thanks, I got it to compile now.

And I suggest a good soaking for the keyboard, a week drying, and then using it. I hope you've got a backup.
Title: C++ Help.
Post by: kasperl on August 01, 2004, 06:25:13 am
OK, WTF?

I got the entire thing to work, without problems. I add a new CPP file, and put a new class in there, ini. I add some basic output messages to the constructor, using the message thingy we just build, and now it says "illegal pure syntax, must be '= 0' about the line where I define the OutputLevel.

I changed nothing on that line, what the hell is going on?

Edit: I updated the stuff on the FTP, www.sectorgame.com/FSCZ/kaserl/temp/builder2/
Title: C++ Help.
Post by: kasperl on August 01, 2004, 02:37:24 pm
www.sectorgame.com/FSCZ/kasperl/temp/Builder2.rar
Title: C++ Help.
Post by: WMCoolmon on August 01, 2004, 09:20:26 pm
Well, your class definition doesn't have a closing bracket or semicolon and there's a random semicolon right after iniparse.h is included.

(Typing on my backup, an MS Natural Keyboard)
Title: C++ Help.
Post by: ChronoReverse on August 01, 2004, 09:24:03 pm
What compiler are you using?  It should be telling you these things.
Title: C++ Help.
Post by: PeachE on August 01, 2004, 10:27:57 pm
on iniparse:

for one thing, it looks like you're using some version of visual studio, so stop using ".h" on iostream and fstream. stop it now!

second, on your iniparse.cpp you define a constructor for ini that takes a character array. delete the word "void". constructors do not have a return type. you also need to close your ini class. so at the bottom of iniparse.h, right before #endif, add  "};"

another thing you need to do is identify the namespace of cout. unless you want to write "std::cout" everytime, i suggest at the top of the files that use this function, right under the includes, type "using namespace std;"

also, in your main function, both of your input parameters are named argv. name one of them argc (there's a convention for this - i think it's the first one but i'm not sure).

one last thing. you're defining OutMessage after you use it (same with the const SendLevel) and you're defining it twice. you'll never need two definitions unless you overload, but  a good tip is to put all your helper functions and global consts in a seperate header file(s) and then include that when you need them.


if you are using Visual studio, and you make all these changes you'll still get an error along the lines of: iniparse.obj already contains an instance of OutMessage..blah... if you do, it's because VS is trying to be friendly. VS tries to automatically do the work of a makefile and i believe links all the files in the same namespace for you, so you don't need the usual #include "iniparse.h". (don't take my word on this one though - it's been a while since i've done c++ - i've got c# on the brain this week)
Title: C++ Help.
Post by: PeachE on August 01, 2004, 10:30:21 pm
oh, and i've got work tomorrow, so i don't have time to go through the whole thing right now. but i'll try to check it out later this week and see what's up.
Title: C++ Help.
Post by: Kosh on August 02, 2004, 01:20:01 am
C++ compilers have a tendency to be a bit....twitchy. Sometimes they will give you out of memory errors even though there is plenty of free system memory.
Title: C++ Help.
Post by: kasperl on August 02, 2004, 05:59:02 am
Yeah, I'm using VC6.

When I remove the H I get an error.

Why the namespace thingy, everything works now, right?

I overloaded the message thingy on purpose, and I put it in a seperate file by now.

I'll re-upload, but everything works now, thanks to some help from Kazan and you guys.
Title: C++ Help.
Post by: PeachE on August 02, 2004, 08:25:53 am
Quote
Originally posted by kasperl
When I remove the H I get an error


hmm.. might just be a dotNet thing. dunno. like i said, been a while since i've done c++

Quote
Why the namespace thingy, everything works now, right?


the way it is now, it won't work on every compiler. when i compiled it, i got errors like "cout not found". if you add the using namespace line, it will prevent this.

Quote
I overloaded the message thingy on purpose, and I put it in a seperate file by now.


ah, i didn't notice that one took an int and one took a character pointer. coo' but yeah, they should still go in another file.
Title: C++ Help.
Post by: FreeTerran on August 02, 2004, 11:05:10 am
well i had a c++ problem too i try to learn it :)

but if i compile the code i get some weird errors

Code: [Select]
#include

int main ()
{
  cout << "Hello World! ";
  cout << "I'm a C++ program";
  return 0;
}


i'm using vc++ 6.0 and this tutorial http://www.cplusplus.com/doc/tutorial/tut1-1.html

errors:
Code: [Select]
D:\Programme\cpp-dev\projects\main.c(7) : error C2065: 'cout' : undeclared identifier
D:\Programme\cpp-dev\projects\main.c(7) : error C2297: '<<' : illegal, right operand has type 'char [14]'
D:\Programme\cpp-dev\projects\main.c(8) : error C2297: '<<' : illegal, right operand has type 'char [18]'


i hope someone could help me :nervous:
Title: C++ Help.
Post by: aldo_14 on August 02, 2004, 11:25:34 am
Shouldn't you have something next to that #include?  

EDIT need #include [iostream.h] (with < brackets instead of square) - that defines the standard, IIRC, C++ IO library for sending output messages to the screen (etc).  (that's also why it doesn't recognise cout, that'll be defined in iostream)
Title: C++ Help.
Post by: FreeTerran on August 02, 2004, 11:29:31 am
mhh they dosen't copy it into the post but its in the source ;)

#include < iostream.h >

without the spaces^^
Title: C++ Help.
Post by: aldo_14 on August 02, 2004, 11:33:55 am
I presume you've got your classpaths (Java term, not sure if it's different for C++) setup so it can find the iostream.h file?  (i.e. have you got the previous  code to work)
Title: C++ Help.
Post by: FreeTerran on August 02, 2004, 11:50:38 am
I check that the directory where iostream.h is located is included in vc++ 6.0 :(
Title: C++ Help.
Post by: PeachE on August 02, 2004, 12:03:23 pm
try this instead

Code: [Select]
#include < iostream >
using namespace std;
Title: C++ Help.
Post by: FreeTerran on August 02, 2004, 12:09:11 pm
ok i found the error filename was main.c but must be a c++ file so .cpp :)
Title: C++ Help.
Post by: milo on August 02, 2004, 05:37:37 pm
Quote
Originally posted by WMCoolmon
When you're checking for a null pointer, if(pFirst == 0) should be if(pFilrst == NULL), it is considered bad practice to assume null pointers are 0; although they are on Win32 and Linux, I believe.

Actually, the standard says that null pointers must be integral constants that evaluate to zero, even if the underlying physical representation of the pointer does not have all bits set to zero.  It is perfectly safe to use if (pFirst == 0) or even if (!pFirst) in any C++ program.  

Of course, individual programming teams may choose to use other syntax as a matter of personal preference.