Help me with my game command please :<

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?
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.
Umm... could you show me how do you do it using substring? I'm kinda slow on this.
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.
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
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();
}
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
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
Topic archived. No new replies allowed.