C++ Compile error with classes and objects.
Author |
Message |
wtd
|
Posted: Fri Dec 15, 2006 7:57 pm Post subject: (No subject) |
|
|
To clarify, you should use endl instead of the string literal "\n". However, I am referring to things like declaring function parameters as:
rather than:
|
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
Craige

|
Posted: Fri Dec 15, 2006 8:24 pm Post subject: (No subject) |
|
|
wtd wrote: To clarify, you should use endl instead of the string literal "\n". However, I am referring to things like declaring function parameters as:
rather than:
Oh, yeah. Wasn't thinking about that. And while I still believe there is nothing wrong with C style strings, i have been switching everything over. |
|
|
|
|
 |
OneOffDriveByPoster
|
Posted: Sat Dec 16, 2006 12:07 am Post subject: (No subject) |
|
|
Well, there is more than style to look at here. (Some more style too though).
main.cpp
c++: |
// ...
int main (int argc, char *argv) // char **argv; but are you going to use these?
{
// ...
MadLibs madLibsHandle; // I really don't like "handle" (don't know why); comments wtd?
while ( command != 'q' && command != 'Q' ) // could use "break" in loop (or not)
{
// ...
command = getchar(); // could cause trouble
// ...
if ( command == 'w' ) { /*...*/ } // nice place for a switch...
else if ( command == 'a' ) { /*...*/ } // "fall through" to handle 'w' vs. 'W'
}
return 0;
}
|
madlibs.h
c++: |
// ...
using namespace std; // generally not good for headers (can't be bad to avoid this early)
class MadLibs
{
private:
// ...
bool ReadFile( char *libname ) { /*...*/ } // consider char const *libname or std::string const &libname
// ...
public:
// ...
};
|
|
|
|
|
|
 |
Craige

|
Posted: Sat Dec 16, 2006 12:46 pm Post subject: (No subject) |
|
|
OneOffDriveByPoster wrote: Well, there is more than style to look at here. (Some more style too though).
main.cpp
c++: |
// ...
int main (int argc, char *argv) // char **argv; but are you going to use these?
{
// ...
MadLibs madLibsHandle; // I really don't like "handle" (don't know why); comments wtd?
|
Yes, I will be using char **argv. I'm going to use it to allow automatic opening of files, or anything else in the initial menu. Why is it**argv though?
Quote: c++: |
while ( command != 'q' && command != 'Q' ) // could use "break" in loop (or not)
{
|
So you mean use an infinate loop, and just check the command in the loop, and break if it's q (|| Q)
Quote: c++: |
// ...
command = getchar(); // could cause trouble
|
So I see. It leaves the enter character in the input buffer, doesn't it?
Quote: c++: |
// ...
if ( command == 'w' ) { /*...*/ } // nice place for a switch...
else if ( command == 'a' ) { /*...*/ } // "fall through" to handle 'w' vs. 'W'
}
return 0;
}
|
Can't use a switch statement if I'm going to check for 'q' || 'Q' in loop and break. Or atleast that check can't be part of the switch and would have to be an if. Maybe switch would be more suitable though.
Quote:
madlibs.h
c++: |
// ...
using namespace std; // generally not good for headers (can't be bad to avoid this early)
|
Okay.
Quote: c++: |
class MadLibs
{
private:
// ...
bool ReadFile( char *libname ) { /*...*/ } // consider char const *libname or std::string const &libname
|
I'm switching it to std::string const &libname
Quote: c++: |
// ...
public:
// ...
};
|
Thanks for all the help you guys have been giving. I know the community I come from wouldn't have given a shit about all of this. It's good to talk to some people who do. |
|
|
|
|
 |
md

|
Posted: Sat Dec 16, 2006 1:03 pm Post subject: (No subject) |
|
|
I see nothing wrong with char **argv, so long as you realize that it's read only and you are careful not to try reading from a null pointer. I also see nothing wrong with your loop control, though replacing it with a boolean do_exit type structure might be better, for example
code: | bool do_exit = false;
while( !do_exit )
{
...
switch( comand )
{
case 'q':
case 'Q':
do_exit = true; break;
case 'w':
case 'W':
... ; break;
}
}
|
Also see how a switch can be used, unless you call break execution will continue into the next case. |
|
|
|
|
 |
Craige

|
Posted: Sat Dec 16, 2006 1:08 pm Post subject: (No subject) |
|
|
md wrote: I see nothing wrong with char **argv, so long as you realize that it's read only and you are careful not to try reading from a null pointer. I also see nothing wrong with your loop control, though replacing it with a boolean do_exit type structure might be better, for example
code: | bool do_exit = false;
while( !do_exit )
{
...
switch( comand )
{
case 'q':
case 'Q':
do_exit = true; break;
case 'w':
case 'W':
... ; break;
}
}
|
Okay. Maybe I'll do that then. I see how the do_exit would be cleaner.
Quote:
Also see how a switch can be used, unless you call break execution will continue into the next case.
Yep, I know. |
|
|
|
|
 |
wtd
|
Posted: Sat Dec 16, 2006 1:23 pm Post subject: (No subject) |
|
|
md wrote:
code: | bool do_exit = false;
while( !do_exit )
{
...
switch( comand )
{
case 'q':
case 'Q':
do_exit = true; break;
case 'w':
case 'W':
... ; break;
}
}
|
SOmething you may wish to consider is using a "continue" statement after the "do_exit = true;" statement. "break" will only exit the switch statement. Code after that but inside the loop will still be executed. One can, however, skip to the next iteration of the loop by using a continue statement instead. |
|
|
|
|
 |
OneOffDriveByPoster
|
Posted: Sat Dec 16, 2006 1:42 pm Post subject: (No subject) |
|
|
Quote: Yes, I will be using char **argv. I'm going to use it to allow automatic opening of files, or anything else in the initial menu. Why is it**argv though?
It's char **argv (or char *argv[], etc.) because it acts like a passed array of C strings. Each argument you pass in would usually be a separate string in this array. argv[0] is usually the name of your program executable.
Quote: So you mean use an infinate loop, and just check the command in the loop, and break if it's q (|| Q)
Yes.
Quote: So I see. It leaves the enter character in the input buffer, doesn't it?
Yes. It might be better to read the whole line too. That depends on how you want the input to be like though.
Quote: Can't use a switch statement if I'm going to check for 'q' || 'Q' in loop and break. Or atleast that check can't be part of the switch and would have to be an if. Maybe switch would be more suitable though.
"goto" is not all evil. Consider it a labelled break. Saves you the problem that wtd pointed out. |
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
md

|
Posted: Sat Dec 16, 2006 7:32 pm Post subject: (No subject) |
|
|
OneOffDriveByPoster wrote:
"goto" is not all evil. Consider it a labelled break. Saves you the problem that wtd pointed out.
I'm sorry... but you are dead wrong. Goto is stupendously evil. continue and break are only evil too but because they operate in well defined ways they are not so evil as to avoid using. Goto on the other hand is completely totally mind-blowingly evil. There is no reason ever to resort to spaghetti code, not ever no matter what. wtd pointed out a potential problem (one that I would consider very small, if everything happens in the switch anways) AND the correct solution to it. |
|
|
|
|
 |
wtd
|
Posted: Sat Dec 16, 2006 7:39 pm Post subject: (No subject) |
|
|
md wrote: OneOffDriveByPoster wrote:
"goto" is not all evil. Consider it a labelled break. Saves you the problem that wtd pointed out.
I'm sorry... but you are dead wrong. Goto is stupendously evil. continue and break are only evil too but because they operate in well defined ways they are not so evil as to avoid using. Goto on the other hand is completely totally mind-blowingly evil. There is no reason ever to resort to spaghetti code, not ever no matter what. wtd pointed out a potential problem (one that I would consider very small, if everything happens in the switch anways) AND the correct solution to it.
Yet continue is really just a tamed form of goto.
There are different kinds of goto. Local gotos are not evil, but nor should they be one's first choice. |
|
|
|
|
 |
Craige

|
Posted: Sat Dec 16, 2006 10:37 pm Post subject: (No subject) |
|
|
Okay, I'm starting to work on the methods now. I've started with the WriteLib method, and I have created another one you will see in a few seconds.
I once again have a compile error, due to type conversions (and one due to and object.) So, if I have a function defined to return std::string, how would I make it return a character from a variable? I tried doing a type cast on it, but that didn't work. It still gives me the compile error:
madlibs.h:46: invalid conversion from `char' to `const char*'
I also have a compile error:
madlibs.h:79: request for member `HandleCharacter' in `this', which is of
non-aggregate type `MadLibs*'
Why would I be getting that on the this object? It's automatically defined.
Here's the code:
c++: |
class MadLibs
{
private:
std::ifstream rfile;
std::ofstream wfile;
std::string WriteBuffer;
std::string ReadBuffer;
bool ReadFile( std::string const &libname )
{
// read code
}
bool WriteFile( std::string const &libname, std::string &data )
{
// write code
}
std::string HandleCharacter ( char character, bool &quit )
{
// Handle Characters
switch ( (int)character )
{
case 1: // <ctl> + a - Adjective Input
return "<adjective>";
break;
case 4: //<ctl> + q - Quit
quit = true;
break;
case 13: // newline
return "\n";
break;
case 14: // <ctl> + n - Noun Input
return "<noun>";
break;
case 22: // <ctl> + v - Verb Input
return "<verb>";
break;
default:
/*46:*/ return (std::string)character;
break;
}
}
public:
MadLibs()
{
// code implimented later
}
void WriteLib ( void )
{
char letter;
std::string LibBuffer;
bool complete = false;
std::cout << "Write Lib" << std::endl
<< "--------------" << std::endl
<< "Special Key Sequances:" << std::endl
<< "<ctl> + v .................... Verb Input" << std::endl
<< "<ctl> + n .................... Noun Input" << std::endl
<< "<ctl> + a .................... Adjective Input" << std::endl << std::endl;
std::cout << "Begin Composition:" << std::endl << std::endl;
while ( complete != true )
{
letter = getch();
/*79:*/ std::cout << this.HandleCharacter(letter, &complete);
}
}
void ReadLib ( void )
{
std::cout << "Read Lib";
}
};
|
|
|
|
|
|
 |
md

|
|
|
|
 |
Craige

|
Posted: Sat Dec 16, 2006 10:49 pm Post subject: (No subject) |
|
|
md wrote: instead of a cast use std::string(1, character); For more constructors/methods see http://www.cppreference.com/cppstring/
Oh wow, I didn't resize the string type was an object. Thanks. 1 down. |
|
|
|
|
 |
OneOffDriveByPoster
|
Posted: Sat Dec 16, 2006 11:48 pm Post subject: (No subject) |
|
|
Craige wrote: 1 down.
For the other: "this" is a pointer in C++. |
|
|
|
|
 |
Craige

|
Posted: Wed Dec 20, 2006 12:23 pm Post subject: (No subject) |
|
|
Okay, that fixed it. It compiles now. However, there is something wrong with the <ctrl> + d case of the switch in the method. It outputs a whole load of random stuff. Well, actually, the first time it seemed to be a bunch of Windows enviorment variables, but it's not now.
Is it the way I'm settig &quit? I havn't done much with pass by refrence before, so I may be setting it wrong, or maybe even passing it wrong.
Sorry for all the questions. I really want to pick up C++. I stated it before, but never went anywhere with it. This time I'm deturmaned to get a base in it, so I can move on with my programming. |
|
|
|
|
 |
|
|