Pode esta função ser mais seguro? À procura de dicas e seus pensamentos!
Pergunta
Este é um pouco de uma pergunta estranha.
Eu escrevi uma função C. Sua 'como' strchr / strrchr. É suposto olhar para um personagem de uma c-corda, mas indo para trás, e retornar um ponteiro para ele. Como strings C não são "nulo iniciado", ele também tem um terceiro parâmetro 'count', indicando o número de caracteres que deve olhar para trás.
/*
*s: Position from where to start looking for the desired character.
*c: Character to look for.
*count: Amount of tests to be done
*
* Returns NULL if c is not in (s-count,s)
* Returns a pointer to the occurrence of c in s.
*/
char* b_strchr(const char* s,int c,size_t count){
while (count-->0){
if (*s==c) return s;
s--;
}
return NULL;
}
Eu fiz alguns testing sobre ele, mas Você vê alguma falhas nele? problemas de segurança ou assim? Quaisquer melhorias? Poderia ser melhorado? E o mais importante:? Esta é uma má idéia
Alguns uso.
char* string = "1234567890";
printf("c: %c\n",*b_strchr(string+9,'5',10));//prints 5
printf("c: %c\n",*b_strchr(string+6,'1',7));//prints 1
EDIT: Nova interface, algumas mudanças
./*
* from: Pointer to character where to start going back.
* begin: Pointer to characther where search will end.
*
* Returns NULL if c is not between [begin,from]
* Otherwise, returns pointer to c.
*/
char* b_strchr(const char* begin,int c,const char* from){
while (begin<=from){
if (*from==c) return from;
from--;
}
return NULL;
}
Solução
É melhor com a edição, mas a interface ainda é surpreendente. Eu ia colocar o parâmetro begin
(o palheiro que está sendo pesquisado) como o primeiro parâmetro, o parâmetro c
(O agulha que está sendo procurado) segundo, eo parâmetro from
(posição inicial da pesquisa) em terceiro. Essa ordem parece ser idiomática em uma bastante grande conjunto de APIs.
Outras dicas
O código tem uma interface esotérica - Passar para um ponteiro para o último caractere da string e o comprimento da corda. Isso vai levar a problemas de usá-lo.
(Alternativamente, o código tem um bug -. Você deve adicionar contagem de s antes do loop)
Se começar é a partir, o código atual sempre retornará começar, o que não é o que você quer. O código após o loop pode ser apenas NULL retorno. E em vez de começar! = A partir da condição de loop, eu usaria começar Edit: pensando bem desde que você quer [começar, a partir] inclusivo deve ser começar <= de
Eu escrevi uma função C. Sua 'como' strchr / strrchr.
Você tentou strrchr()
reinventar, por isso não é como strchr()
.
Você vê quaisquer falhas nele?
Sim. De várias. : - (
Desde b_strchr()
pode retornar NULL
, você não deve colocá-lo diretamente na declaração printf()
. Deferencing NULL
geralmente resulta em um segfault.
Você pode ser melhor fora com a sua variação favorita de ...
char *result;
result = b_strchr(string + 9, 'a', 10));
if (result == NULL)
{
printf("c: NULL\n");
}
else
{
printf("c: %c\n", *result);
}
Além disso, quando
(count >= length of the input string) and the character is not found
você está indo para obter resultados unpredicable porque s
não está apontando para um caractere na cadeia - s
está apontando para a memória antes do início da cadeia. Como exemplo, tente
result = b_strchr(string + 9, 'a', 11));
if (result == NULL)
{
printf("c: NULL\n");
}
else
{
printf("c: %c\n", *result);
}
e ver o que acontece.
Expanda seus casos de teste de uso para incluir condições fora do que você sabe que vai funcionar com sucesso. Pedir a alguém para ajudá-lo a projetar casos de teste que realmente vai testar seu código.
E o mais importante:? Isto é uma má idéia
Como um exercício de aprendizagem, absolutamente não.
No entanto, neste caso, por código de produção que você seria melhor fora de furar a strrchr()
padrão.