Pode esta função ser mais seguro? À procura de dicas e seus pensamentos!

StackOverflow https://stackoverflow.com/questions/1077479

  •  21-08-2019
  •  | 
  •  

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;
}
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top