19.05.2012, 16:26
(
Последний раз редактировалось rjjj; 09.07.2012 в 11:57.
)
Pawn Strings.
Por rjjj ou Ken
Por rjjj ou Ken
Em programaзгo, string й a denominaзгo de uma sequкncia de caracteres (letras, nъmeros, sнmbolos). Ela, quando em um cуdigo, pode ser encontrada na forma de uma palavra, de uma frase ou atй de um texto .
O objetivo da utilizaзгo de strings й basicamente a elaboraзгo de expressхes que venham a ter um significado em algum momento da execuзгo do programa.
Nem toda letra de um cуdigo-fonte й necessariamente parte de uma string. Na linha abaixo por exemplo, o trecho SendClientMessageToAll, por mais que seja um sequкncia de caracteres, nгo й uma string :
pawn Код:
SendClientMessageToAll(0xFFFFFFAA, "Oi");
Porйm o trecho "Oi" й, devido а equivalкncia que hб entre o mesmo e uma palavra durante a leitura do cуdigo, diferentemente de SendClientMessageToAll, que por sua vez tem o papel de adicionar mensagens ao chat de todos os jogadores.
1 - Declaraзгo.
Em Pawn, pode-se declarar uma string de duas maneiras .
A primeira й atravйs da delimitaзгo com aspas (" ") do que desejamos que seja uma string:
pawn Код:
"Sou uma string"
A segunda й a inserзгo do operador de stringizing (#) na frente do que serб a string:
pawn Код:
#Sou uma string
Tambйm й possнvel fazer isso atravйs do preenchimento de uma variбvel array com certos valores e atravйs de funзхes como strcat, mas esse jб й um tipo mais implнcito de declaraзгo.
2 - Armazenamento.
Para que uma string seja processada ela precisa estar armazenada em uma variбvel array .
As seguintes sentenзas expressam as relaзхes existentes entre uma string e a array que a contйm:
Код:
Se uma string estб contida em uma variбvel array, cada caractere da string estб contido em uma parte da array. Se uma variбvel array tem tamanho igual a x ela poderб armazenar uma string de no mбximo (x - 1) caracteres.
Essa ъltima sentenзa pode ser explicada pelo fato de as strings sempre terminarem com um caractere especial chamado EOS (acrфnimo para "End Of String", fim de string em inglкs), que na prбtica nгo й um caractere integrante.
Exemplos:
pawn Код:
new x[3] = "AB"; //A variбvel array x armazena a string "AB".
new y[4] = #lol; //A variбvel array y armazena a string "lol".
new z[4] = "mano"; //A variбvel array z armazena a string "mano" (?).
Й comum pensar que todos os cуdigos acima estгo corretos, mas nгo estгo .
No ъltimo caso tenta-se armazenar uma string de 4 caracteres em uma variбvel array de tamanho 4, o que desobedece uma das regras que citei no inнcio desta seзгo do tutorial.
Para evitar ter que saber o total de caracteres da string para designar o tamanho da variбvel array que a conterб, pode-se utilizar o seguinte truque:
pawn Код:
new Var[] = "Pawn";
Deixando os colchetes ([ ]) vazios, o tamanho da array serб calculado automaticamente durante a compilaзгo. Isso sу funciona quando a string a ser armazenada for igualada а variбvel durante sua inicializaзгo.
Em outros casos serб necessбrio colocar nos colchetes um nъmero grande o suficiente para permitir o armazenamento de qualquer uma das strings que possam vir.
Quando criamos uma variбvel array sem especificar os elementos que a mesma conterб, esses valores acabam sendo zeros. Como o valor de EOS й zero, uma variбvel como essa armazena um tipo de string, a de tamanho nulo:
pawn Код:
new x[10] = ""; //A variбvel array x contйm a string de tamanho nulo.
new y[10]; //A variбvel y tambйm contйm a string de tamanho nulo.
3 - Composiзгo.
pawn Код:
new pow[7] = "nъmero";
A variбvel array do cуdigo acima tem esta composiзгo :
pawn Код:
pow[0] contйm o caractere n.
pow[1] contйm o caractere ъ.
pow[2] contйm o caractere m.
pow[3] contйm o caractere e.
pow[4] contйm o caractere r.
pow[5] contйm o caractere o.
pow[6] contйm o caractere EOS.
Note que os caracteres da string interna ficam ordenados. Graзas a isso й possнvel executar um loop que substitua, em uma string, o caractere o pelo a, por exemplo.
Usando o exemplo da string em pow, se eu quisesse transformar "nъmero" em "nъmera", faria isto:
pawn Код:
pow[5] = 'a';
Quando queremos trabalhar com um caractere individualmente como no caso acima, delimitamos o mesmo com apуstrofos (' ').
Obterнamos o mesmo resultado se tivйssemos feito isto:
pawn Код:
pow[5] = 97;
Mas por quк ?
Porque nъmeros e caracteres de strings estгo associados de acordo com a tabela de sнmbolos ASCII.
Por esse motivo sempre poderemos construir uma string apenas com nъmeros:
pawn Код:
new o[3] = {97, 102, 0};
//Й o mesmo que:
new o[3] = {'a', 'f', '\0'};
//Que й o mesmo que:
new o[3] = "af";
4 - Packed Strings.
Quando uma variбvel й declarada no cуdigo Pawn a mesma й destinada a ocupar uma parte da memуria do computador durante o processamento do arquivo .amx (resultado da compilaзгo) .
O elemento correspondente a uma variбvel scalar (nгo-array) na memуria chama-se cell, e tem um tamanho de 4 bytes (32 bits).
Como variбveis arrays sгo estruturas de dados elas podem originar vбrias cells. A quantidade dessas cells й igual ao nъmero que й colocado dentro do par de colchetes ([ ]) ao lado do nome da variбvel array, na criaзгo da mesma .
Quando a array й multidimensional o total de cells que serгo originadas й igual ao produto dos valores dentro dos pares de colchetes.
Exemplo:
pawn Код:
new Circulo; //Essa variбvel originarб 1 cell.
new Quadrado[3]; //Essa variбvel originarб 3 cells.
new Triangulo[10][20]; //Essa variбvel originarб 200 cells.
Como vimos anteriormente quando uma string estб armazenada em uma variбvel array, cada caractere da mesma, contando com o EOS, fica em uma parte da array.
Um caractere ASCII sempre terб um tamanho de no mбximo 1 byte (8 bits) devido а constituiзгo binбria dos nъmeros que sгo equivalentes a eles (0 a 255).
Entгo, se uma parte de uma variбvel array tem tamanho de 4 bytes e um caractere de 1 byte, quando uma string й formada, 3 bytes por caractere ficam inutilizados.
E й aн que entram as packed strings, que sгo strings em que cada caractere ocupa 1 byte, ou seja, 1/4 de uma parte da array.
Para declarar uma packed string basta colocar o sнmbolo ! na frente da string:
pawn Код:
new STR[4] = !"Packed string";
A string acima, contando com o EOS, contйm 14 caracteres.
Entгo a variбvel array STR deveria ter um tamanho de no mнnimo 14 bytes.
Como cada parte de array tem tamanho de 4 bytes, й impossнvel criar uma array de apenas 14 bytes, por isso escolhemos o menor tamanho possнvel, 16 bytes (4 cells) .
No fim acabamos armazenando uma string de 13 caracteres em uma array de tamanho 4.
Para trabalhar com um caractere de uma packed string em particular fazemos o seguinte:
pawn Код:
new PKD[1] = !"Oie";
printf("%c", PKD{0}); //Mostraria o caractere O.
printf("%c", PKD{1}); //Mostraria o caractere i.
printf("%c", PKD{2}); //Mostraria o caractere e.
PKD{0} = 'A'; //Trocaria o caractere O pelo A, na string.
print(PKD); //Imprime a packed string "Aie".
//Obs: PKD{3} conteria o EOS.
Obs: Uma cell do SA-MP Pawn tem um tamanho fixo de 32 bits.
Poucas funзхes que trabalham somente com strings suportam packed strings (como strpack e strunpack, que convertem uma string para packed string e vice-versa), o que й um dos motivos desse recurso ser raramente usado.
5 - Manipulaзгo.
Nessa parte do tutorial explicarei as tйcnicas de manipulaзгo de strings :
* Concatenaзгo
Concatenaзгo й a uniгo de strings baseada na junзгo do fim de uma com o inнcio de outra.
Para realizar esse processo durante a inicializaзгo da variбvel array que armazenarб a string resultante pode-se colocar as strings a serem unidas uma ao lado da outra :
pawn Код:
new Array[] = "SA-MP" "Fуrum"; //Seria o mesmo que colocar "SA-MP Fуrum".
Quando as strings estгo em arrays, deve-se usar a funзгo strcat, que significa "string concatenation" (ou "string concatenate"), concatenaзгo de strings em inglкs:
Exemplo:
pawn Код:
new Pawn[20] = "Script";
strcat(Pawn, "ing"); //Concatena a string na variбvel Pawn e a string "ing".
print(Pawn); //Mostra a string "Scripting".
* Inserзгo
Na inserзгo de strings, uma string й inserida em outra.
Durante a inicializaзгo da array que conterб a string final, podemos fazer isto, por exemplo, para inserir a substring (string interna) "estб" na string "Onde esse indivнduo ?":
pawn Код:
new Exemplo[] = "Onde" "estб" "esse indivнduo ?";
A funзгo desenvolvida para inserir strings em outras й o strins, que significa "string insertion" (ou "string insert"), inserзгo de strings em inglкs:
Exemplo:
pawn Код:
new Pawn[20] = "Й ing";
strins(Pawn, "script", 2); //Insere a string "script" de modo que o primeiro caractere dela passe a ocupar Pawn[2].
print(Pawn); //Mostra a string "Й scripting".
* Deleзгo
Na deleзгo de strings, parte de uma string й removida.
Quando conhecemos a string em detalhes, podemos apenas apagб-la, obviamente.
Mas quando nгo sabemos podemos utilizar esta propriedade se o que se quiser for apenas remover caracteres a partir do comeзo da string :
Код:
Se uma string x estб armazenada em uma variбvel array y, o dado y[z], se considerado string, serб igual а x sem os z primeiros caracteres.
Exemplo:
pawn Код:
new Config[20] = "Settings";
print(Config[2]); //Mostra a string "ttings".
Caso contrбrio utilizamos a funзгo strdel, que й "string deletion" (ou "string delete"), deleзгo de strings em inglкs. Ela й de "propуsito geral" no campo da deleзгo de strings:
Exemplo:
pawn Код:
new Letras[5] = "ABCD";
strdel(Letras, 1, 3); //Apaga os caracteres em Letras[1] e Letras[2], ignorando o em Letras[3] para frente.
print(Letras); //Mostra a string "AD".
* Extraзгo
Fazer a extraзгo de uma string й, como o nome diz, obter uma substring de uma string.
Quando a string nгo estб armazenada em uma array, basta copiar uma parte dela .
Mas quando estб, aplicamos a funзгo strmid, que significa "string middle", "metade de string" em inglкs, uma referкncia а capacidade da mesma.
Exemplo:
pawn Код:
new Tipo[6] = "MySQL";
new Linguagem[4];
strmid(Linguagem, Tipo, 2, 5); //Armazena na variбvel Linguagem a string formada por Tipo[2], Tipo[3] e Tipo[4], ignorando Tipo[5] para frente.
print(Linguagem); //Mostra a string "SQL".
* Comparaзгo
Para comparar duas strings utilizamos a funзгo strcmp, que significa "string comparison" (ou "string compare"), comparaзгo de strings em inglкs.
Essa funзгo retorna o nъmero zero se as strings passadas aos seus dois primeiros parвmetros forem iguais, e um nъmero diferente de zero se forem diferentes:
Exemplo:
pawn Код:
new A[6] = "Alpha";
new B[5] = "Beta";
if(strcmp(A, B) == 0) //Checa se as strings em A e B sгo iguais.
{
print("As variбveis A e B contкm a mesma string."); //Se forem, uma mensagem й exibida.
}
* Encontramento
Para facilitar a procura de uma string dentro de outra, a funзгo strfind ("string find", encontrar string em inglкs) foi desenvolvida.
Ela tenta encontrar a string passada ao seu segundo parвmetro dentro da string direcionada ao primeiro parвmetro. Retorna -1 se a string nгo tiver sido encontrada .
Exemplo:
pawn Код:
new Nome[7] = "Ken_xD";
new Cla[3] = "xD";
if(strfind(Nome, Cla) != -1) //Checa se a string da variбvel Cla foi encontrada dentro da string da variбvel Nome.
{
print("Ken_xD й do clг xD."); //Se a string for encontrada, um mensagem й exibida.
}
* Tokenizaзгo
Tokenizaзгo й o processo de segmentaзгo de uma string em outras menores, denominadas tokens.
Para executar uma tokenizaзгo podemos utilizar a funзгo strtok, que significa "string tokenization" (ou "string tokenize"), tokenizaзгo de strings em inglкs. Apesar de nгo ser uma funзгo padrгo, strtok vem definida em boa parte dos GMs que vкm com a pasta server do SA-MP .
Esse cуdigo porйm, pelo menos na versгo encontrada nesses GMs, considera como delimitador das substrings que serгo tokens sempre o caractere ASCII 32 (espaзo).
Exemplo:
pawn Код:
new STR[] = "Groove domina o parque";
new Indice;
print(strtok(STR, Indice)); //Mostra a string "Groove".
print(strtok(STR, Indice)); //Mostra a string "domina".
print(strtok(STR, Indice)); //Mostra a string "o".
print(strtok(STR, Indice)); //Mostra a string "parque".
Para uma tokenizaзгo com qualquer delimitador, recomenda-se o plugin sscanf.
* Formataзгo
Bem, a formataзгo й flexнvel a ponto de substituir por exemplo strcat em um cуdigo.
Entretanto a funзгo responsбvel por isso й mais lenta, por isso бs vezes pode nгo agradar aqueles que gostam de otimizar ao mбximo .
Trata-se da funзгo format.
Ao primeiro parвmetro do format deve-se passar a variбvel array na qual se quer armazenar a string formatada, ao segundo o nъmero mбximo de caracteres de string contando com o EOS que a array pode conter, e ao terceiro o formato de string a ser assumido.
Nesse terceiro parвmetro podem ser colocados sнmbolos chamados placeholders, que durante a execuзгo do cуdigo, sгo substituнdos ordenadamente pelos valores que sгo colocados na elipse no fim do format.
Os placeholders mais comuns sгo:
Код:
%s (й substituнdo por uma string). %d ou %i (й substituнdo por um nъmero inteiro). %f (й substituнdo por um ponto flutuante, isto й, um nъmero racional).
Exemplo:
pawn Код:
new Tudo[23];
new Individuo[] = "O menino";
new Nota = 8;
format(Tudo, 23, "%s tirou nota %d", Individuo, Nota); //%s e %d sгo substituнdos, nessa ordem, pelo conteъdo das variбveis Individuo e Nota.
print(Tudo); //Mostra a string "O menino tirou nota 8".
6 - Caractere de escape.
A barra invertida (\) nгo й um caractere comum, pois pode concatenar linhas de strings e de diretivas de prй-processador, alйm de permitir a participaзгo de caracteres especiais em strings .
Por exemplo, nгo hб nenhum sнmbolo que podemos colocar em strings para se referir ao caractere ASCII 7, que й nгo-imprimнvel.
Entгo utilizamos o chamado caractere de escape, a barra invertida:
pawn Код:
print("A"); //Mostra o caractere ASCII 65.
print("\7"); //Mostra o caractere ASCII 7.
Como as aspas em Pawn servem para indicar strings e como a barra invertida й o prуprio caractere de escape, estes precisam do caractere de escape para serem exibidos:
pawn Код:
print("\""); //Mostra um dos sнmbolos de aspas.
print("\\"); //Mostra uma barra invertida.
Para escolher o caractere de escape, basta colocar o seguinte cуdigo no topo do GM:
pawn Код:
#pragma ctrlchar 'x' //Troque x pelo novo caractere de escape.
Espero ter ajudado .