Esta función puede ser más seguro? En busca de consejos y sus pensamientos!
Pregunta
Esto es algo así como una pregunta extraña.
Me escribió una función C. Su 'como' strchr / strrchr. Se supone que debe buscar un personaje de una c-cadena, pero yendo hacia atrás, y devuelven un puntero a ella. Como cadenas de C no son "nulo iniciaron", también se necesita un tercer parámetro 'contar', que indica el número de caracteres que debe mirar hacia atrá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;
}
He hecho algunas pruebas en él, pero ¿Ha observado algunos defectos en ella? Las cuestiones de seguridad más o menos? Las mejoras? Se podría mejorar? Y más importante: ¿Es esta una mala idea
Algunos 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: Nueva interfaz, algunos cambios
./*
* 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;
}
Solución
Es mejor con la edición, pero la interfaz sigue siendo sorprendente. Yo pondría el begin
parámetro (el pajar siendo interrogados) como primer parámetro, el parámetro c
( aguja que se busca) segundo, y el tercer parámetro from
(posición de inicio de búsqueda). Esa orden parece ser idiomática a través de una bastante grande conjunto de APIs.
Otros consejos
El código tiene una interfaz esotérica - Ir a un puntero al último carácter de la cadena y la longitud de la cadena. Que dará lugar a problemas de usarlo.
(Como alternativa, el código tiene un error - se debe añadir a la cuenta s antes del bucle.)
Si el inicio es de, el código actual y con Gusto comenzar, lo cual no es lo que quiere. El código después del bucle solo puede ser NULL retorno. Y en lugar de comenzar! = A partir de la condición del bucle, utilizaría empezar Editar: pensándolo bien, ya que desea [comenzará, a partir] inclusiva debe empezar <= a
Me escribió una función C. Su 'como' strchr / strrchr.
Ha intentado reinventar strrchr()
, por lo que no es como strchr()
.
¿Ves algún defecto en ella?
Sí. Varios. : - (
Desde b_strchr()
puede volver NULL
, no debería ponerlo directamente en el printf()
comunicado. Deferencing s
por lo general resulta en una violación de segmento.
Usted puede ser mejor con su variante favorita de ...
char *result;
result = b_strchr(string + 9, 'a', 10));
if (result == NULL)
{
printf("c: NULL\n");
}
else
{
printf("c: %c\n", *result);
}
Además, cuando
(count >= length of the input string) and the character is not found
vas a obtener resultados unpredicable porque ya no es <=> señalando un carácter de la cadena - <=> está señalando a la memoria antes de que el principio de la cadena. A modo de ejemplo, intente
result = b_strchr(string + 9, 'a', 11));
if (result == NULL)
{
printf("c: NULL\n");
}
else
{
printf("c: %c\n", *result);
}
y ver qué pasa.
Amplíe sus casos de prueba de uso para incluir condiciones fuera de lo que sabe va a funcionar correctamente. Pedir a otra persona para ayudarle a diseñar casos de prueba que realmente pondrá a prueba su código.
Y más importante: ¿Es esta una mala idea
?
Como un ejercicio de aprendizaje, absolutamente no.
Sin embargo, en este caso, por el código de producción que sería mejor de pegarse con el estándar <=>.