Help me with my game command please :<

Nov 5, 2018 at 3:04pm
I'm currently adding a new feature "/msg" to a game that I'm modifying. The command works like "/msg name message". However, I'm having issue to identify which is the name and which is the message. Is using substring function possible to create this command?
Nov 5, 2018 at 3:51pm
You could use substring to find when the 2nd space is, yes.
Another way to do is to combine the >> operator with std::getline.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Example program
#include <iostream>
#include <string>

int main()
{
    std::string command;
    
    std::cout << ">";
    std::cin >> command;
    
    if (command == "/msg")
    {
        std::string username;
        std::cin >> username;
        
        std::string command_contents;
        std::getline(std::cin, command_contents);
  
        std::cout << "Sending the message \"" << command_contents << "\" to username \"" << username << "\"" << std::endl;
    }
}


>/msg aaa bbb ccc
Sending the message " bbb ccc" to username "aaa"

Note this isn't perfect, because it leaves the space at the beginning of the message, but logic can be easily added to remove this.
Nov 5, 2018 at 4:05pm
Umm... could you show me how do you do it using substring? I'm kinda slow on this.
Nov 5, 2018 at 5:11pm
If you show an attempt at solving your problem it will help all of us.

Some examples of using substr are in:
http://www.cplusplus.com/reference/string/string/substr/

You might also be interested in find:
http://www.cplusplus.com/reference/string/string/find/
For example, you could use find to look for spaces.
Nov 5, 2018 at 5:13pm
This is my code. However, string "name" and string "message" is not called, because that is that part that I'm confused with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
else if (str.substr(0, 5) == "/msg ") {
						ENetPeer * currentPeer;

						for (currentPeer = server->peers;
							currentPeer < &server->peers[server->peerCount];
							++currentPeer)
						{
							if (currentPeer->state != ENET_PEER_STATE_CONNECTED)
								continue;

							

							if (((PlayerInfo*)(currentPeer->data))->rawName == name) {
								if (((PlayerInfo*)(currentPeer->data))->haveGrowId == false) continue;
								GamePacket ps = packetEnd(appendString(appendString(createPacket(), "OnConsoleMessage"), "`o>> Private msg from `0" + ((PlayerInfo*)(peer->data))->trueName + "`o (`$in" + ((PlayerInfo*)(peer->data))->currentWorld + "`o) : " + message + "`o"));
								ENetPacket * packet = enet_packet_create(ps.data,
									ps.len,
									ENET_PACKET_FLAG_RELIABLE);
								enet_peer_send(currentPeer, 0, packet);
								delete ps.data;

							}
						}
					}


"/msg name message"
How do I obtain string name and string message?
I've read all the tutorials on this forum on how to find string between 2 spaces using substring, but I still don't get it...
Last edited on Nov 5, 2018 at 5:37pm
Nov 5, 2018 at 6:27pm
By the way you can also use string stream
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <sstream>

int main() {

	std::string message{ "/msg god Hello god, can I please have the last cookie?" }; 
	std::istringstream iss{ message };

	std::string command;
	iss >> command;

	std::string username;
	iss >> username;

	std::string msg;
	getline(iss, msg);

	std::cout << "Command: " << command << "\nUsername: " << username << "\nMessage: " << msg;

	std::cin.get();
}
Nov 5, 2018 at 6:33pm
If you must use substr, here's one way to do it.
In the end, you'll get a string for "username", and a string for the actual message itself. Do with that what you will.

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// Example program
#include <iostream>
#include <string>

///
/// Parses a command sent to see if it's a /msg command,
/// and if so, returns true and puts the username and message to be sent
/// into username_out and message_out, respectively.
///
bool parse_message_command(const std::string full_command, std::string& username_out, std::string& message_out)
{
    const std::string msg_token = "/msg ";
    
    if (full_command.substr(0, msg_token.size()) == msg_token)
    {
        // assumes username immediately starts at index[5]
        size_t space_after_username_index = full_command.find(" ", msg_token.size());
        
        if (space_after_username_index != std::string::npos)
        {
            username_out = full_command.substr(msg_token.size(), space_after_username_index - msg_token.size());
            message_out  = full_command.substr(space_after_username_index);
            
            if (message_out.size() >= 1)
                message_out.erase(0, 1); // pop initial space off, if any.
            
            return (message_out != "") && (username_out != "");
        }
        else
        {
            return false;
        }
    }

    return false;
}

int main()
{
    // get the username and message from user input
    std::string full_command;
    std::cout << ">";
    std::getline(std::cin, full_command);
    
    // variables to store the username and message in
    std::string username;
    std::string message;
    
    // get the username and message
    if (parse_message_command(full_command, username, message))
    {
        // use the username and message
        std::cout << "Sending message \"" << message << "\" to \"" << username << "\"..." << std::endl;
    }
    else
    {
        std::cout << "Unknown command or incorrect syntax" << std::endl;
    }
}

>/msg Charlie This is a message for Charlie!!!
Sending message "This is a message for Charlie!!!" to "Charlie"...


>/msg
Unknown command or incorrect syntax


>/msg Charlie
Unknown command or incorrect syntax



This also assumes there's only 1 space between the /msg and the username, and the actual message. If you want whitespace between the tokens to not matter, there is a different solution.

Last edited on Nov 5, 2018 at 6:38pm
Nov 5, 2018 at 6:49pm
Here's a method that doesn't care about whitespace between "/msg" and "username" and "the actual message". I would prefer this to the substr mess...

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
   
#include <iostream>
#include <string>
#include <sstream>

///
/// Parses a command sent to see if it's a /msg command,
/// and if so, returns true and puts the username and message to be sent
/// into username_out and message_out, respectively.
///
bool parse_message_command(const std::string full_command, std::string& username_out, std::string& message_out)
{
    std::istringstream iss(full_command);
    std::string msg_token;
    if (iss >> msg_token && msg_token == "/msg")
    {
        std::string username_token;
        if (iss >> username_token)
        {
            std::string start_of_message;
            
            // get first token of the actual message
            if (iss >> start_of_message)
            {
                std::string rest_of_message;
                getline(iss, rest_of_message);
                
                message_out = start_of_message + rest_of_message;
                username_out = username_token;
                
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

int main()
{
    // get the username and message from user input
    std::string full_command;
    std::cout << ">";
    std::getline(std::cin, full_command);
    
    // variables to store the username and message in
    std::string username;
    std::string message;

    // get the username and message
    if (parse_message_command(full_command, username, message))
    {
        // use the username and message
        std::cout << "Sending message \"" << message << "\" to \"" << username << "\"..." << std::endl;
    }
    else
    {
        std::cout << "Unknown command or incorrect syntax" << std::endl;
    }
}


>/msg    Charlie      Message for....       Charlie!
Sending message "Message for....       Charlie!" to "Charlie"...
Last edited on Nov 5, 2018 at 6:52pm
Topic archived. No new replies allowed.