Function Problems

Pages: 1234
Thanks guys, almost solved the problem. Now I gotta find a way to store and adapt the array.
Here's what I got if your interested in trying to figure it out before I do.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enum type_t { T_NUL = 0, T_STR = 1, T_NUM = 2, T_FLT = 3, T_BLN = 4 };
struct option {
	char* name;
	enum type_t type;
	union {
		char* vstr;
		int vint;
		float vflt;
		bool vbln;
	};
};
struct option opt (int number, char* variable = "") {
	option val;
	switch (number) {
	case 0: { val.name = "Option 0"; val.type = T_STR; val.vstr = "Hello"; } break;
	case 1: { val.name = "Option 1"; val.type = T_NUM; val.vint = 0; } break;
	case 2: { val.name = "Option 2"; val.type = T_BLN; val.vbln = false; } break;
	default: { val.name = "Unrecognised Option"; val.type = T_NUL; } break;
	}
	return val;
}
Don't know why but iostream is throwing errors on my compiler so I'm going with this alternitive.
Edit: Also I'll later use the variable pointer to load the option by name instead and ignore the number (which is used for loading entire array via a loop in main function).
Last edited on
Disch wrote:
INT, UNIT, UCHAR_PTR, etc are bad choices for variable names since they're #defined as actual types by various libs (WinAPI)


Yes you are right.

Actually I'm beginning to fee a bit guilty about encouraging him in these evil ways....
Last edited on
Don't worry about the names, I plan to append AWS_ to them before completing the app anyway
@awsdert

Can we not dissuade you from this madness?

What about a nice option class?

Something more along these lines?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <vector>
#include <string>

class opt_t
{
private:
	std::vector<std::string> arg_list;
public:
	opt_t(int argc, const char* argv[])
	: arg_list(argv, argv + argc)
	{
	}

	int get_int(const std::string& arg);
	float get_float(const std::string& arg);
	double get_double(const std::string& arg);
	std::string get_string(const std::string& arg);
};

int main(int argc, const char* argv[])
{
	opt_t opts(argc, argv);

	int s = opts.get_int("-size");
	float t = opts.get_float("-temp");

	return 0;
}


Last edited on
If this is all just to parse command line arguments, why not just do something like
1
2
3
4
5
6
7
8
struct CLA{
	bool option1;
	std::string option2;
	int option3;
	enum{ A, B, C } option4;
	CLA(int argc,char **argv);
	void reset();
};
?
*sigh*

Look, I personally love using "evil" features of C++ (there's so much I can do with them and I never mess them up when I keep a small log), but many others here don't. Apparently, not even Duoas' method is "good".

If you expect to get assistance from anyone other than myself on these forums, you will have to use "good" code. Sorry, but that's the way it is. :(

Oh, and if you want to parse command line arguments, then to check what the characters are, try <ctype.h>.
http://cplusplus.com/reference/clibrary/cctype/

And if you declare that something's an integer or a float, put it into one of the ato functions.
http://cplusplus.com/reference/clibrary/cstdlib/

-Albatross
Last edited on
Sorry, but what I'm after is a list of Options & their values. Since I highly doubt all my options will have the same type of value I need an adaptable function. I tried putting it inside an actual array but that just threw errors. If someone knows how to use struct inside an array or a link to an explanation then I would greatly appriciate it.
Edit:I was typing when you posted those - They're not to parse cmdline options (those will be handled inside the main function) they're to handle options from a file e.g. sos.config.
Albatross, I agree - evil features are the best when used correctly which is why I overtest any code I write (includes web code) so that there are as little problems as possible.
Last edited on
I really don't see why you need to put the options in an array. You're not going to iterate over the options, are you? Your accesses would just look like arguments.get("option1"). How is that better than arguments.option1?
Last edited on
If by list of options you mean argv[]... you do mean argv, no?

Or am I missing something?

-Albatross
Last edited on
I just saw this.
I was typing when you posted those - They're not to parse cmdline options (those will be handled inside the main function) they're to handle options from a file e.g. sos.config.
Oh... Well, that changes things somewhat.

You could have this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class config_file{
	std::map<std::string,std::string> values;
public:
	config_file(const char *filename);

	Type get_type(const std::string &key);

	std::string get_string(const std::string &key);
	int get_integer(const std::string &key);
	//more getters

	void set_string(const std::string &key,std::string &value);
	void set_integer(const std::string &key,int value);
	//more setters

	void write(const char *filename);
};
get_type() only applies if you want the file to have strong typing. You could determine the type of the value based on whether it appears in the file as value=15 or value="15". Otherwise, you just have the getters perform conversions as needed.
Obviously, everything is stored as strings.
Last edited on
Thanks but I have 2 questions:
Where'd this key & value come from?
How would this later be used?
Obviously, the constructor opens the file, reads it, and parses it. Alternatively, you could create an empty config_file and have the application fill it with configuration data that will later be saved with config_file::write().

As for how to use it, like I said, it depends on the kind of typing you using.
1
2
3
4
5
6
7
8
9
//strong typing
if (file.get_type("option")==Type::string)
    std::cout <<file.get_string("option");
else if (file.get_type("option")==Type::integer)
    std::cout <<file.get_integer("option");

//weak typing
std::cout <<file.get_string("option");
std::cout <<file.get_integer("option");
Well that was certainly helpful but not really what I was getting at. Do I need to use the FILE type beforehand to load the data or will this work as is?
What do you mean?
What I mean is do I have to do somthing like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FILE sos_cfg;
config_file file;
sos_cfg.open("sos.config");
// Parse the names and values into file
sos_cfg.close();
delete sos_cfg;
char* typ;
int cnt;
typ = file.get_type(opt_names[0]);
for (cnt = 0; cnt < opt_list_length;cnt++) {
    switch (typ) { // printf is used here in place of data handling
    case INT: printf("%s = %d", opt_names[cnt], file.get_int(opt_names[cnt]); break;
    // list of cases and their actions
    default: puts("Error could not determine type"); break;
    }
}
delete file;
And by the way you still haven't told me where the key pointer came from.
I'm sorry, but I have to ask. Did you start learning C++ last week? You've managed to cram quite a few mistakes in very few lines. The worst one is that FILE is a C type and that you're trying to delete a non-pointer.

The class definition I gave you should be self-explanatory. A filename is passed to the constructor and it does all the work of opening parsing the file. A use of the class should look simply like
1
2
config_file cfg("file.cfg");
std::cout <<cfg.get_string("option");

And I shouldn't even need to mention this, but the parameters named 'key' are references, not pointers.
That clears things up quite a bit, I wasn't sure that the code knew that it was loading a file. As for the key thing did you mean that it's like the argv & co that are in main() normally?

As for when I started learning C++ it was about 3 weeks ago since that is when I finally found out about Code::Blocks (it was only today that I learnt MS Visual Studio registration keys were free though) however I didn't really have much time for it though so my only real experience has been the last couple of days where I wasn't using project templates and just started from blank projects.
Actually, argv[] is only in main if you require it to be in main, like

int main(int argc, char * argv[])

And key is a reference. Not a pointer. It uses & not *.

-Albatross
Last edited on
As for the key thing did you mean that it's like the argv & co that are in main() normally?
No. I mean they're references.
http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29
Ok, now I understand what you mean, however what is / are the keys referencing?
Are they referencing the 1st or 2nd std::string from the std::map or are they referencing somethig else entirely?
Pages: 1234