A type..with a number in brackets...

Pages: 12
if I make an array of string elements..is there a way to figure out how many elements are in that array?


There are two I can think of offhand. One is a tricky use of templates:

1
2
3
4
5
6
7
8
9
10
// tricky template version
template <typename T,unsigned S>
unsigned ArraySize(const T (&t)[S])
{
    return S;
}

// to use:
int foo[100];
cout << ArraySize(foo);  // outputs 100 


Another way is to use sizeof:
1
2
3
int foo[100];

cout << sizeof(foo) / sizeof(int);  // outputs 100 


Note both of the above work with fixed array names only. If you have a pointer to an array or a dynamically allocated array, then you cannot get the size of it. You'll have to store the size of the array seperately.

Is it true that instead of using array's [snip] That I should always use vector's instead..I read that somewhere..is that true?


Not always.

If the array size is dynamic, then yes, you're usually better off with a vector or deque (for the same reasons you're better off with a string instead of a char array).

But if the array size is fixed, then there's no much to gain from using vector.
OK, so what I will do is just pass the size of the array into the function as a separate parameter...since I know the size of all my array's, atleast for this situation.

I really appreciate it. For awhile if I have anymore questions and stuff I will also ask here..because I want to continue to save space. I am afraid I will have a lot of questions in the next few days..because I am really doing a lot with this..so hopefully I can keep it all here and avoid taking up space on the forums.

Thank you very much for all the help.

One more quick question...
is it safe to do this:
1
2
3
4
    std::string choices[3];
    choices[1] = "1) Go to the police station.";
    choices[2] = "2) Call the police station.";
    choices[3] = "3) Throw away the mail you got from the police station.";

Since it normally starts at 0, can't you specify that you want it to start at 1?
I usually do it this way in PHP so it's easier to keep track of how many elements are in the array, is this a safe practice in C++ as well?
Since it normally starts at 0, can't you specify that you want it to start at 1?


No, that's not safe, and no you can't do it in C++.

Get in the habit of starting from 0. AFAIK PHP is zero-based as well... it probably is just resizing the array to 1 larger when you step out of bounds like that. C++ won't do that though, and stepping out of array bounds is one of the causes of the most horrible of horrible bugs.

Starting from 0 makes more logical sense anyway. Just get it in your brain that that's how it's supposed to be.
I think your right..I might even rethink the way I do it in PHP, so that's good..that's why I wanted to learn C++, because I can take the stuff I learn from it and apply it to PHP which I have been doing for 7 years..maybe I can learn more about PHP from learning C++< not to mention when I start digging into new languages..it will be even better because I have the C++ experience. Thanks again.
What does:

C:\xampp\htdocs\cpp projects\Police Simulator 1\functions.h: In function `int option_creator(std::string*, int, std::string)':
C:\xampp\htdocs\cpp projects\Police Simulator 1\functions.h:87: warning: control reaches end of non-void function

For this function..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
    Function: option_creator
    Description: Based off passed parameters, allows you to get a option result from a user
*/
int option_creator(std::string options[], int size, std::string message = "Please select an option...") {
    std::cout<<message;

    int increment = 0;
    while (increment < size) {
        std::cout<<options[increment]<<std::endl;
        increment++;
    }
    int response;
    std::cin>>response;
    std::cin.ignore();
    if (response > size) {
        option_creator(options, size, message);
    }else {
        return response;
    }
}

This compiles and runs entirely correct..it just throws that warning for some reason..what does that mean..I call the function as below:
1
2
3
4
5
6
    std::string choices[3];
    choices[0] = "1) Go to the police station.";
    choices[1] = "2) Call the police station.";
    choices[2] = "3) Throw away the mail you got from the police station.";

    int response = option_creator(choices, 3, "Please choose..");
It means it's possible for the code to reach the end of the function without returning anything.

Take a look here:

1
2
3
4
5
6
    if (response > size) {
        option_creator(options, size, message);
    }else {
        return response;  // return inside of "else"
    }
} // end of function 


Notice that you only return a value if the 'else' is taken. If response > size, then the else is skipped and the end of the function is reached without you returning anything.

======================

Other things I feel compelled to point out:

1) Your while() loop on line 9 seem like it'd be better suited as a for() loop. There's nothing wrong with a while loop, mind you, it just seems strange that you would choose while over for in that situation.

2) Don't recurse like this to repeat input (ie: don't have option_creator call itself). If the user inputs something invalid and you want to repeat code -- put the repeating code in a loop.
Well I had an alternative function (kindly written for me by another member of the forum), I really liked it and used it to write a shorter version..this. If I don't recurse like that, it'll be impossible for me to make sure they input the right data, correct?
I was thinking of this as a measure to make sure..if the answer they entered is not within the bounds of the allowed options, it re-runs in order to make them enter the input again..is there any idea as to a better way to do it?

Regarding the first option..the reason I did while was because it was shorter..I started with the while look at first to be honest but it was throwing errors...then I found out I cannot get the size of an array easily so I just passed the size in instead..I will look into that again.
Out of curiosity is.. http://www.cprogramming.com/tutorial/lesson16.html
a possible way to do this? Is what I did with recursion bad for some reason..based off the stuff I tried this was the only way I was able to make this actually work..because it kept exiting out without me recalling that function.
Based off what you told me a minute ago..I tried the ONLY other thing I could thing of..based off what you said and what I saw elsewhere I was able to put together:
1
2
3
4
5
6
7
8
9
10
11
12
13
int option_creator(std::string options[], int size, std::string message = "Please select an option...") {
    std::cout<<message;
    do {
        for (int increment = 0; increment < size; increment++) {
            std::cout<<options[increment]<<std::endl;
        }
        int response;
        std::cin>>response;
        std::cin.ignore();
    }while(response > size);

    return response;
}

for the function but it doesn't work..the other thing I had worked, but this ends up returning:

C:\xampp\htdocs\cpp projects\Police Simulator 1\functions.h||In function `int option_creator(std::string*, int, std::string)':|
C:\xampp\htdocs\cpp projects\Police Simulator 1\functions.h|80|error: `response' was not declared in this scope|
||=== Build finished: 1 errors, 0 warnings ===|
OK..it works. That's all I needed for now..I can't believe that you were right.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
    Function: option_creator
    Description: Based off passed parameters, allows you to get a option result from a user
*/
int option_creator(std::string options[], int size, std::string message = "Please select an option...") {
    std::cout<<message;
    int response;
    do {
        for (int increment = 0; increment < size; increment++) {
            std::cout<<options[increment]<<std::endl;
        }
        std::cin>>response;
        std::cin.ignore();
    }while(response > size);

    return response;
}

Does the SAME thing but a lot faster. I was able to change it to a for loop..and get rid of the recursive, as well as make it work.

Thank you VERY much, this works perfectly..with very little code.
If I don't recurse like that, it'll be impossible for me to make sure they input the right data, correct?


No. You can put the input section in a loop. A do/while loop is often good for validating input:

1
2
3
4
do
{
  // get user input
}while(user_input_is_bad);


the loop will keep running until the user inputs something appropriate.

Recursion is something that should generally be avoided.


(I'm still not sure why recursion is taught so early in C/C++ programming courses... as it is something that only has practical use in a relatively small set of circumstances, and isn't very commonplace in programs... but that's another topic)


EDIT:

you're a quick one. I see you figured it out while I was still replying. heh.

Nice. That funciton is a lot better than your previous one.
Last edited on
Yes, I just realized what you were talking about. I pieced something together and put it in code above in my last post, thank you very much. This works great.
Hi, had a little question.
I had a function that I found..it kind of forces them into Fullscreen mode by emulating the keystroke for alt-enter.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void FullScreen()
{
	keybd_event(VK_MENU,
                0x38,
                0,
                0);
    keybd_event(VK_RETURN,
                0x1c,
                0,
                0);
    keybd_event(VK_RETURN,
                0x1c,
                KEYEVENTF_KEYUP,
                0);
    keybd_event(VK_MENU,
                0x38,
                KEYEVENTF_KEYUP,
                0);
}

I am using that even on command line apps..and it requires the window.h
I want to see if there is another way to do this without doing it this way..
because right now this throws an error for Window's Vista and won't let it open..
I was thinking..if there a way to fake it and make it work on any system..or overrule that vista error or something...
I can't really test how this app will work in command line because of that vista problem.
Also is this method generally accepted:
1
2
3
4
5
6
7
8
9
10
11
            std::cout<<"You decide it might be better to visit them in person to see what they wanted to speak about. The next morning you get in your ";
                <<"car and head towards the police station, in which you filled out the application.  When you get there, you see the police chief sitting ";
                <<"at his desk.  You walk up to him, and mention your name and tell him you got a letter in the mail pertaining to your application.";
                <<std::endl;
                <<"It takes a minute before the police chief even notices your presence. He seems really wrapped up in the papers on his desk, and ";
                <<"doesn't even pay you notice until you clear your throat.";
                <<std::endl;
                <<"\"Is there something I can help you with sir?\" say's the police chief...";
                <<std::endl;
                <<"You inquire about your application.  The police chief tells you to wait a second, and he heads to the back of the room in order to ";
                <<"pull up your application. Within about 10 minutes, he returns and has the application in hand. 

That same general format when c'outing a bunch of text at once..or is there a better way to do that?
You have extra ';' at the end of your lines that you don't want (except for the last one, where you are missing a closing " and the ;). But otherwise yeah, I do that all the time, especially for long lines like that which might cause someone to scroll to screen horizontally.

And an FYI, C and C++ will automatically combine string literals for you if they are next to each other, separated only by whitespace, so you can do stuff like this:

1
2
3
4
std::cout<<"this"
" is "
"all "
"one string.";
Topic archived. No new replies allowed.
Pages: 12