Jump to content

[C++] Cum să lucrezi cu parametrii dintr-un string


Andreigl
 Share

Recommended Posts

Dacă ai lucrat în cleo vreodată, atunci știi că poți afla parametrii în felul următor:

SAMP.IsCommandTyped(0@)
0AD4: 4@ = scan_string 0@ format "%s %d %s" 1@v 5@ 6@v

și unde 4@ returnează numărul de parametrii (evident, în cazul nostru sunt 3, dar nu am pus-o ca și o condiție, deci nu-i obligatoriu să fie 3).

 

În C++, pentru un mod SF, ce mi-a venit în cap, pentru a afla numărul de parametrii, putem verifica numărul de spații.

De exemplu, se află un spațiu? Atunci avem 2 parametrii, nu se află nici un spațiu? Atunci avem unul singur.

 

Funcția următoare ne dă numărul de parametrii:

int params_count = 0;
for (unsigned int contor = 0; contor < params.length(); contor++)
	if (params[contor] == ' ')
		params_count++;

 

Cu funcția următoare putem verifica dacă jucătorul a trimis cel puțin un parametru:

if (!params.empty())
	std::cout << "Avem cel putin un parametru";
else
	std::cout << "Nu avem nici un parametru";

 

Putem să verificăm dacă a trimis într-adevăr parametrii de care noi avem nevoie:

if (!sscanf_s(params.c_str(), "%d %d", Player_ID, Licence_ID))
{
	SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), "{00d12d}[School Instructors]: {a1aba2}Usage: /gl(givelicense) [Player ID] [License ID]");
	SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), "{00d12d}[School Instructors]: {a1aba2}ID Licenses: Flying (1), Sailing (2), Fishing (3), Weapon (4), Materials (5)");
	return;
}

 

Un exemplu de utilizare (am început eu să traduc un mod CLEO în C++):

void __stdcall Announcements::GiveLicense(std::string params)
{
	unsigned int params_count = 0;
	for (unsigned int contor = 0; contor < params.length(); contor++)
		if (params[contor] == ' ')
			params_count++;

	if (params.empty() || params_count == 0)
	{
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), "{00d12d}[School Instructors]: {a1aba2}Usage: /gl(givelicense) [Player ID] [License ID]");
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), "{00d12d}[School Instructors]: {a1aba2}ID Licenses: Flying (1), Sailing (2), Fishing (3), Weapon (4), Materials (5)");
		return;
	}

	int* Player_ID = new int;
	int* Licence_ID = new int;
	if (!sscanf_s(params.c_str(), "%d %d", Player_ID, Licence_ID))
	{
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), "{00d12d}[School Instructors]: {a1aba2}Usage: /gl(givelicense) [Player ID] [License ID]");
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), "{00d12d}[School Instructors]: {a1aba2}ID Licenses: Flying (1), Sailing (2), Fishing (3), Weapon (4), Materials (5)");
		free(Player_ID);
		free(Licence_ID);
		return;
	}

	if (SF->getSAMP()->getPlayers()->IsPlayerDefined(*Player_ID))
	{
		if (*Licence_ID >= 1 && *Licence_ID <= 5)
		{
			if (*Licence_ID == 1)
			{
				char* Event = new char[256];
				snprintf(Event, 256, "/givelicense %d Flying", *Player_ID);
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Event);
				free(Event);
			}
			if (*Licence_ID == 2)
			{
				char* Event = new char[256];
				snprintf(Event, 256, "/givelicense %d Sailing", *Player_ID);
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Event);
				free(Event);
			}
			if (*Licence_ID == 3)
			{
				char* Event = new char[256];
				snprintf(Event, 256, "/givelicense %d Fishing", *Player_ID);
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Event);
				free(Event);
			}
			if (*Licence_ID == 4)
			{
				char* Event = new char[256];
				snprintf(Event, 256, "/givelicense %d Weapon", *Player_ID);
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Event);
				free(Event);
			}
			if (*Licence_ID == 5)
			{
				char* Event = new char[256];
				snprintf(Event, 256, "/givelicense %d Materials", *Player_ID);
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Event);
				free(Event);
			}
		}
		else
		{
			SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), "{00d12d}[School Instructors]: {a1aba2}Wrong License ID.");
			SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), "{00d12d}[School Instructors]: {a1aba2}ID Licenses: Flying (1), Sailing (2), Fishing (3), Weapon (4), Materials (5)");
		}
	}
	else
	{
		char Message[256];
		_snprintf_s(Message, sizeof(Message), "{00d12d}[School Instructors]: {a1aba2}Player with ID %d is not connected.", *Player_ID);
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), Message);
	}

	free(Player_ID);
	free(Licence_ID);
}

 

Singura problemă, care încă nu i-am dat de furcă, funcția say ne cere pointerul unui string, însă _snprintf_s nu poate implementa un pointer (noi ca să citim parametrii pe rând, folosim sscanf, iar aici trebuie să creem pointeri din nou). Eu am folosit în schimb snprintf, dar o să primim warning cum că funcția este unsecure. Bine înțeles, se poate dezactiva acest warning. Revin cu edit când o să găsesc o soluție.

Edited by shanker'
update
Link to comment
Share on other sites

Varianta 2, folosind tutorialul lui @Vesca (Click pentru a accesa tutorialul):

main.h

class Announcements {
public:
	static void __stdcall GiveLicense(std::string);
	static void __stdcall At_Me(std::string);
	static void __stdcall StartLesson(std::string);
	static void __stdcall TestPassed(std::string);
	static void __stdcall TestFailed(std::string);
};

std::unordered_map< std::string, std::pair<std::regex, std::string> >
Syntaxes{
	{ "GiveLicence", { std::regex("[0-999]+ [1-5]+"), "<Player ID> <Licence ID>" } },
	{ "At_Me", { std::regex("[0-999]+ [1-5]+"), "<Player ID> <Licence ID>" } }
};

 

main.cpp

void _stdcall Announcements::GiveLicense(std::string params)
{
	std::regex regex_syntax = Syntaxes["GiveLicence"].first;
	if (std::regex_match(params, regex_syntax))
	{
		std::stringstream StringStream(params);
		std::string Player_ID, Licence_ID;
		StringStream >> Player_ID >> Licence_ID;
		if (SF->getSAMP()->getPlayers()->IsPlayerDefined(std::stoi(Player_ID)))
		{
			if (std::stoi(Licence_ID) == 1)
			{
				std::string Format = "/givelicense " + Player_ID + " Flying";
				char* Text = new char[Format.size() + 1];
				strcpy_s(Text, Format.size() + 1, Format.c_str());
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Text);
				free(Text);
			}
			if (std::stoi(Licence_ID) == 2)
			{
				std::string Format = "/givelicense " + Player_ID + " Sailing";
				char* Text = new char[Format.size() + 1];
				strcpy_s(Text, Format.size() + 1, Format.c_str());
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Text);
				free(Text);
			}
			if (std::stoi(Licence_ID) == 3)
			{
				std::string Format = "/givelicense " + Player_ID + " Fishing";
				char* Text = new char[Format.size() + 1];
				strcpy_s(Text, Format.size() + 1, Format.c_str());
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Text);
				free(Text);
			}
			if (std::stoi(Licence_ID) == 4)
			{
				std::string Format = "/givelicense " + Player_ID + " Weapon";
				char* Text = new char[Format.size() + 1];
				strcpy_s(Text, Format.size() + 1, Format.c_str());
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Text);
				free(Text);
			}
			if (std::stoi(Licence_ID) == 5)
			{
				std::string Format = "/givelicense " + Player_ID + " Materials";
				char* Text = new char[Format.size() + 1];
				strcpy_s(Text, Format.size() + 1, Format.c_str());
				SF->getSAMP()->getPlayers()->pLocalPlayer->Say(Text);
				free(Text);
			}
		}
		else
		{
			std::string Text = "{00d12d}[School Instructors]: {a1aba2}Player with ID " + Player_ID + " is not connected.";
			SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), Text.c_str());
		}
	}
	else
	{
		std::string Text_Syntax = "{00d12d}[School Instructors]: {a1aba2}Syntax: " + Syntaxes["GiveLicence"].second;
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xFF, 0), Text_Syntax.c_str());
	}
}
Link to comment
Share on other sites

Imi place maxim modul in care explici, detaliezi si pui problema. Congrats!

On 2/13/2020 at 12:28 PM, Jackson Brooklyn said:

*Topicurile in care nu se posteaza pentru o perioada mai mare de 72 de ore vor fi inchise, fiind deschise ulterior la cerere (in caz ca doriti sa faceti un update) printr-un PM unui Programmer.

:topic_closed:

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.