paulo1205
(usa Ubuntu)
Enviado em 02/03/2018 - 02:04h
Permita-me alguns comentários.
Khyser escreveu:
void getString(char _string[], size_t _size){
fgets(_string, _size, stdin);
Seria bom você colocar aqui uma validação do funcionamento de
fgets(), para ter certeza de que a leitura foi bem sucedida e que a string lida é válida. Caso ocorresse uma falha, seria bom também que a função indicasse isso a quem a chamou, o que sugere que o tipo de retorno não deveria ser
void.
Assim sendo, você poderia começar do seguinte modo.
int getString(char *_string, size_t _size){
if(!fgets(_string, _size, stdin))
return 0;
size_t sizeOfString=strlen(_string)-1;
if(_string[sizeOfString]=='\n'){
_string[sizeOfString]='\0';
}
sizeOfString=strlen(_string);
Você poderia evitar a segunda chamada a
strlen(), que percorre a string toda novamente, fazendo do seguinte modo.
size_t sizeOfString=strlen(_string)-1;
if(_string[sizeOfString]=='\n'){
_string[sizeOfString]='\0';
sizeOfString--;
}
char character[]="'";
for(size_t n=0; n<sizeOfString; n++){
if(_string[n]==character[0]){
_string[n]='t';
}
}
Como você tem um caráter só a ser substituído, poderia evitar o uso de um array para
character.
Se o conjunto de caracteres problemáticos tivesse mais de um elemento, então você poderia fazer algo como o seguinte.
for(char *p=_string; *p; p++)
if(strchr(inavlidCharacters, *p))
*p='t';
Por fim, como agora a função tem de indicar se foi bem sucedida ou não, cabe indicar que, se chegou neste ponto, então realmente foi bem-sucedida.
return 1;
Contudo, eu costumo gostar de separar as coisas. Sua função
getString() não faz apenas
to get uma string, mas também a modifica, com vistas a ser usada como parte de uma consulta SQL de comparação direta de strings (operador “
=” usado na cláusula
WHERE). Eu acharia melhor você ter uma função para ler que fosse separada da função de transformação, ou então que você trocasse o nome da função para refletir o que ela realmente faz.
Além disso, a substituição que você fez é totalmente arbitrária, e pode conduzir a outros bugs. Provavelmente seria melhor você verificar se a string é válida ou não, e rejeitar a consulta totalmente, sem nem mesmo tentar a comunicação com o servidor de banco de dados, se o argumento for inválido.
Pode ser, ainda, que, em alguns contextos, o caráter do apóstrofo seja, sim, válido (uma senha, por exemplo, poderia eventualmente contê-lo, ainda que um nome de usuário não o possa). Nesse caso, seria melhor que, em lugar da substituição arbitrária por uma letra, você usasse a substituição correta, prescrita pelo padrão do SQL, que é o uso de dois apóstrofos consecutivos (semelhante ao que se faz no C, em que é necessário colocar “
\\” numa constante de caráter ou como parte de uma string para obter apenas um sinal “
\”, o como fazem
printf(),
scanf() e suas derivadas, que usam “
%%” para indicar apenas um sinal de percentagem na string formatada). Uma possível implementação dessa função, sem se preocupar em ser eficiente, seria mais ou menos a seguinte.
int escapeForSQLComparison(char *string, size_t max_size){
// O único caráter a ser escapado quando se usa o operador = é o
// apóstrofo, que poderia se confundir com os delimitadores da string;
size_t original_length=strlen(string);
char *escaped_string;
// No pior caso, a string original é formada só de apóstrofos, e todos
// eles terão de ser escapados (cada caráter vira dois caracteres).
if(!(escaped_string=malloc(2*original_length+1)))
return 0; // Falha ao alocar memória para string temporária.
char *src=string, *dst=escaped_string;
do {
if(*src=='\'')
*dst++='\'';
*dst++=*src;
} while(*src++); // Isto é: *src++!='\0'.
const size_t escaped_length=dst-escaped_string;
int retval=0; // Pressupõe falha.
if(max_size>=escaped_length){
retval=1;
if(escaped_length!=original_length){
strcpy(string, escaped_string); // Sobrescreve a string original com a versão escapada.
// Caso contrário, não é preciso fazer nada: a string original já está válida.
}
free(escaped_string); // A string temporária é sempre liberada.
return retval;
}
A função acima, como o nome indica, escapa apenas os caracteres para comparações exatas. Caso você quisesse uma comparação usando o operador
LIKE ou expressões regulares, teria de se preocupar com outros caracteres e possivelmente outras sintaxes.