Cómo Analizar Cadena de seguridad delimitado por tabuladores?
-
27-09-2019 - |
Pregunta
Cómo analizar la seguridad de la cadena tabuladores delimitador? por ejemplo: test \ TBLA-bla-bla \ t2332?
Solución
strtok()
es una función estándar para analizar cadenas con delimitadores arbitrarios. Es, sin embargo, no seguro para subprocesos. Su biblioteca C de elección podría tener una variante flujos seguros.
Otra forma compatible con el estándar (acaba de escribir esto, es no ensayado ):
#include <string.h>
#include <stdio.h>
int main()
{
char string[] = "foo\tbar\tbaz";
char * start = string;
char * end;
while ( ( end = strchr( start, '\t' ) ) != NULL )
{
// %s prints a number of characters, * takes number from stack
// (your token is not zero-terminated!)
printf( "%.*s\n", end - start, start );
start = end + 1;
}
// start points to last token, zero-terminated
printf( "%s", start );
return 0;
}
Otros consejos
Uso strtok_r en lugar de strtok (si está disponible). Tiene uso similar, excepto que es reentrante, y no modificar la cadena como strtok hace. [ Editar En realidad, me equivoqué. Como señala Christoph, strtok_r reemplaza por los delimitadores '\ 0'. Por lo tanto, debe operar en una copia de la cadena si desea conservar la cadena original. Pero es preferible strtok porque es reentrante y segura hilo]
strtok dejará su cadena original modificado. Sustituye el delimitador con '\ 0'. Y si la cadena pasa a ser una constante, almacenado en una memoria de sólo lectura (algunos compiladores lo harán), en realidad se puede obtener una violación de acceso.
Uso strtok()
de string.h
.
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "test\tbla-bla-bla\t2332";
char * pch;
pch = strtok (str," \t");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " \t");
}
return 0;
}
Sin embargo, otra versión; éste separa la lógica en una nueva función
#include <stdio.h>
static _Bool next_token(const char **start, const char **end)
{
if(!*end) *end = *start; // first call
else if(!**end) // check for terminating zero
return 0;
else *start = ++*end; // skip tab
// advance to terminating zero or next tab
while(**end && **end != '\t')
++*end;
return 1;
}
int main(void)
{
const char *string = "foo\tbar\tbaz";
const char *start = string;
const char *end = NULL; // NULL value indicates first call
while(next_token(&start, &end))
{
// print substring [start,end[
printf("%.*s\n", end - start, start);
}
return 0;
}
Si necesita una forma segura binario a tokenize una cadena dada:
#include <string.h>
#include <stdio.h>
void tokenize(const char *str, const char delim, const size_t size)
{
const char *start = str, *next;
const char *end = str + size;
while (start < end) {
if ((next = memchr(start, delim, end - start)) == NULL) {
next = end;
}
printf("%.*s\n", next - start, start);
start = next + 1;
}
}
int main(void)
{
char str[] = "test\tbla-bla-bla\t2332";
int len = strlen(str);
tokenize(str, '\t', len);
return 0;
}