manejo de Cadenas

28/07/2005 - 16:28 por Arturo | Informe spam
Hola a todos, espero que esten bien, en esta ocasion les
pido su ayuda para que me digan que instrucciones puedo
usar para alterar una cadena, los pongo el ejemplo de lo
que quiero:
char cadena[]="(RANCHO, EL)"
Esto al final debe quedar: char cadena[]="(EL RANCHO)"
pero solamente debe ocurrir cuando las palabras despues de
la coma sea: EL, LOS, LA, LAS. En caso de que yo envie:
(TECOLOTES, EJIDO CAMPECHE) no debe hacer nada; en si
siempre que haya un articulo despues de la coma lo haga,
¿Me pueden decir como le hago por favor? Si tiene un
codigo mejor porque apenas estoy aprendiendo C++. De
antemano muchas gracias anticipadas.

Preguntas similare

Leer las respuestas

#11 Isidro Muñoz
01/08/2005 - 21:07 | Informe spam
Hola,

Sin animo de ofender a Willser, y seguramente lo que voy a decir el lo sabe
pero lo comento para quien no lo sepa.

Deben de tener cuidado con los strcpy, porque se pueden producir los
desbordamientos de pila. Es recomendable mejor usar strncpy, donde se indica
el tamaño del buffer donde vamos a escribir.

En nuestro caso


char l_vcCadenaInicial[30] = "(RANCHO,
ELKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFSKDFKSKDFKSKDFK)";
char l_vcSubCadenaDer[30]; // SubCadena después de la coma
strcpy(l_vcSubCadenaDer, l_vcCadenaInicial + l_iPosicionArticulo);

Si la cadena inicial fuera la anterior se produciría un desbordamiento de
pila, tecnica usada por algunos hacker para controlar el ordenador.

Saludos
Isidro

"Willser F. González C." escribió en el mensaje
news:
Cuántas comas (,) podría llegar a tener una cadena?; si es sólo una, sería
que buscara la primer coma coincidente, esta búsqueda le devuelve la
posición donde la encontró, entonces, con base en esa posición se puede
sustraer la subcadena de la izquierda y la de la derecha, esas dos
subcadenas las concatena nuevamente pero en orden inverso y listo, ya


está.
Claro que antes de hacer esta concatenación hay que hacer un ciclo para


que
se determine si la segunda subcadena (la de la derecha) corresponde a un
artículo.

Algo así como:

main()
{
char l_vvcArticulos[4][4] = {"EL", "LA", "LOS", "LAS"};

char l_vcCadenaInicial[30] = "(RANCHO, EL)";

char l_vcSubCadenaDer[30]; // SubCadena después de la


coma
(,).

char l_vcCadenaFinal[30];

char *l_pcPosicionComa = NULL;

unsigned int i, l_iPosicionArticulo = 0;


l_pcPosicionComa = strchr(l_vcCadenaInicial, ','); // Buscar la coma.

l_iPosicionArticulo = l_pcPosicionComa - l_vcCadenaInicial + 2;

if ((l_pcPosicionComa != NULL) &&
(l_iPosicionComa < strlen(l_vcCadenaInicial))) // Coma encontrada.
{
strcpy(l_vcSubCadenaDer, l_vcCadenaInicial + l_iPosicionArticulo);
// Extrae subcadena derecha.

if (l_vcSubCadenaDer[strlen(l_vcSubCadenaDer) - 1] == ')') //
Eliminar el paréntesis.
{
l_vcSubCadenaDer[strlen(l_vcSubCadenaDer) - 1] = 0;

_strupr(l_vcSubCadenaDer); // Convertir a mayúscula por si
acaso.
}

for (i = 0; i < 4; i++) // Para cada artículo.
if (strcmp(l_vcSubCadenaDer, l_vvcArticulos[i]) == 0) // Es un
artículo.
break;

if (i < 4) // Es un artículo.
{
strcpy(l_vcCadenaFinal, "(");
strcat(l_vcCadenaFinal + 1, l_vcSubCadenaDer);
strcat(l_vcCadenaFinal, " ");
strncat(l_vcCadenaFinal, l_vcCadenaInicial + 1,
l_pcPosicionComa - l_vcCadenaInicial - 1);

strcat(l_vcCadenaFinal, ")"); // Aquí queda la cadena final
con el artículo al principio.
}
}
}


Willser F.



"Arturo" escribió en el mensaje
news:006e01c59380$a4d5a910$
Hola a todos, espero que esten bien, en esta ocasion les
pido su ayuda para que me digan que instrucciones puedo
usar para alterar una cadena, los pongo el ejemplo de lo
que quiero:
char cadena[]="(RANCHO, EL)"
Esto al final debe quedar: char cadena[]="(EL RANCHO)"
pero solamente debe ocurrir cuando las palabras despues de
la coma sea: EL, LOS, LA, LAS. En caso de que yo envie:
(TECOLOTES, EJIDO CAMPECHE) no debe hacer nada; en si
siempre que haya un articulo despues de la coma lo haga,
¿Me pueden decir como le hago por favor? Si tiene un
codigo mejor porque apenas estoy aprendiendo C++. De
antemano muchas gracias anticipadas.



Respuesta Responder a este mensaje
#12 Willser F. González C.
01/08/2005 - 22:25 | Informe spam
OK Isidro, la verdad es que lo desconocía.

Sin embargo, haciendo pruebas, al declarar este tipo de variable
inicializada aparace un error de compilación:

error C2117: '(RANCHO,
ELKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFSKDFKSKDFKSKDFK)' : array
bounds overflow

De manera que en este caso no se presentaría esta potencial vulnerabilidad.
Y si el contenido de la variable se asignara en tiempo de ejecución, pienso
que el programador debería preveer que no se exceda el o los límites.

Bueno, es un punto de vista particular, y si la experiencia indica que la
función strcpy() puede llegar a crear vulnerabilidades potenciales; entonces
es mejor seguir su recomendación, porque el que no aprende de consejos
aprende de sus propios errores, y éstos pueden llegar a ser muy costosos.

Mil Gracias,

Willser F.


"Isidro Muñoz" <imunoz@()daipro.net> escribió en el mensaje
news:
Hola,

Sin animo de ofender a Willser, y seguramente lo que voy a decir el lo
sabe
pero lo comento para quien no lo sepa.

Deben de tener cuidado con los strcpy, porque se pueden producir los
desbordamientos de pila. Es recomendable mejor usar strncpy, donde se
indica
el tamaño del buffer donde vamos a escribir.

En nuestro caso


char l_vcCadenaInicial[30] = "(RANCHO,
ELKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFSKDFKSKDFKSKDFK)";
char l_vcSubCadenaDer[30]; // SubCadena después de la coma
strcpy(l_vcSubCadenaDer, l_vcCadenaInicial + l_iPosicionArticulo);

Si la cadena inicial fuera la anterior se produciría un desbordamiento de
pila, tecnica usada por algunos hacker para controlar el ordenador.

Saludos
Isidro

"Willser F. González C." escribió en el mensaje
news:
Cuántas comas (,) podría llegar a tener una cadena?; si es sólo una,
sería
que buscara la primer coma coincidente, esta búsqueda le devuelve la
posición donde la encontró, entonces, con base en esa posición se puede
sustraer la subcadena de la izquierda y la de la derecha, esas dos
subcadenas las concatena nuevamente pero en orden inverso y listo, ya


está.
Claro que antes de hacer esta concatenación hay que hacer un ciclo para


que
se determine si la segunda subcadena (la de la derecha) corresponde a un
artículo.

Algo así como:

main()
{
char l_vvcArticulos[4][4] = {"EL", "LA", "LOS", "LAS"};

char l_vcCadenaInicial[30] = "(RANCHO, EL)";

char l_vcSubCadenaDer[30]; // SubCadena después de la


coma
(,).

char l_vcCadenaFinal[30];

char *l_pcPosicionComa = NULL;

unsigned int i, l_iPosicionArticulo = 0;


l_pcPosicionComa = strchr(l_vcCadenaInicial, ','); // Buscar la coma.

l_iPosicionArticulo = l_pcPosicionComa - l_vcCadenaInicial + 2;

if ((l_pcPosicionComa != NULL) &&
(l_iPosicionComa < strlen(l_vcCadenaInicial))) // Coma
encontrada.
{
strcpy(l_vcSubCadenaDer, l_vcCadenaInicial +
l_iPosicionArticulo);
// Extrae subcadena derecha.

if (l_vcSubCadenaDer[strlen(l_vcSubCadenaDer) - 1] == ')') //
Eliminar el paréntesis.
{
l_vcSubCadenaDer[strlen(l_vcSubCadenaDer) - 1] = 0;

_strupr(l_vcSubCadenaDer); // Convertir a mayúscula por si
acaso.
}

for (i = 0; i < 4; i++) // Para cada artículo.
if (strcmp(l_vcSubCadenaDer, l_vvcArticulos[i]) == 0) // Es
un
artículo.
break;

if (i < 4) // Es un artículo.
{
strcpy(l_vcCadenaFinal, "(");
strcat(l_vcCadenaFinal + 1, l_vcSubCadenaDer);
strcat(l_vcCadenaFinal, " ");
strncat(l_vcCadenaFinal, l_vcCadenaInicial + 1,
l_pcPosicionComa - l_vcCadenaInicial - 1);

strcat(l_vcCadenaFinal, ")"); // Aquí queda la cadena
final
con el artículo al principio.
}
}
}


Willser F.



"Arturo" escribió en el mensaje
news:006e01c59380$a4d5a910$
Hola a todos, espero que esten bien, en esta ocasion les
pido su ayuda para que me digan que instrucciones puedo
usar para alterar una cadena, los pongo el ejemplo de lo
que quiero:
char cadena[]="(RANCHO, EL)"
Esto al final debe quedar: char cadena[]="(EL RANCHO)"
pero solamente debe ocurrir cuando las palabras despues de
la coma sea: EL, LOS, LA, LAS. En caso de que yo envie:
(TECOLOTES, EJIDO CAMPECHE) no debe hacer nada; en si
siempre que haya un articulo despues de la coma lo haga,
¿Me pueden decir como le hago por favor? Si tiene un
codigo mejor porque apenas estoy aprendiendo C++. De
antemano muchas gracias anticipadas.








Respuesta Responder a este mensaje
#13 Isidro Muñoz
02/08/2005 - 21:11 | Informe spam
De nada willser,

El error es porque el compilador sabe de antemano que estas copiando mas
bytes al buffer.
Se ha declarado como 30 bytes y hemos inicializado como un monton.
Te esta fallando en la variable l_vcCadenaInicial no en l_vcSubCadenaDer que
donde se crearía el problema.

De todos modos aunque los hacker puedan usar esta tecnica para controlar el
ordenador. Lo que si es cierto es que si no lo controlas lo mismo en unas
condiciones especiales se produce ese problema en la ejecucion de tu código.
Y estos errores encontrarlos luego te pueden volver loco, son los tipicos
errores que hace cosas raras unas veces sí y otras veces no ( que uno
empieza a actualizar el compilador con todos los parches existentes, el
sistema operativo y demás), y hasta que encuentras que es porque has
sobreescrito mas bytes de la cuenta en la pila te vuelves loco. Existen
herramientas para controlar estas cosas me parece que una es BoundChecker.

El uso de cadenas aconsejo que se use los string de la STL si no se usa MFC,
si se usa MFC creo que la clase es CString, estas clases te abstraen de
reservar memoria, de ampliar los buffers, de liberarle, etc.

Pero mi consejo es que usando funciones de C puro lo suyo es controlar los
buffers, porque luego los bug que pueden generar estas situaciones son
jodidos jodidos.

Creo que Microsoft publico un articulo sobre tecnicas de como evitar los
desbordamientos de pila ¿ alguien lo conoce ?

Saludos
Isidro.

"Willser F. González C." escribió en el mensaje
news:
OK Isidro, la verdad es que lo desconocía.

Sin embargo, haciendo pruebas, al declarar este tipo de variable
inicializada aparace un error de compilación:

error C2117: '(RANCHO,
ELKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFSKDFKSKDFKSKDFK)' : array
bounds overflow

De manera que en este caso no se presentaría esta potencial


vulnerabilidad.
Y si el contenido de la variable se asignara en tiempo de ejecución,


pienso
que el programador debería preveer que no se exceda el o los límites.

Bueno, es un punto de vista particular, y si la experiencia indica que la
función strcpy() puede llegar a crear vulnerabilidades potenciales;


entonces
es mejor seguir su recomendación, porque el que no aprende de consejos
aprende de sus propios errores, y éstos pueden llegar a ser muy costosos.

Mil Gracias,

Willser F.


"Isidro Muñoz" <imunoz@()daipro.net> escribió en el mensaje
news:
> Hola,
>
> Sin animo de ofender a Willser, y seguramente lo que voy a decir el lo
> sabe
> pero lo comento para quien no lo sepa.
>
> Deben de tener cuidado con los strcpy, porque se pueden producir los
> desbordamientos de pila. Es recomendable mejor usar strncpy, donde se
> indica
> el tamaño del buffer donde vamos a escribir.
>
> En nuestro caso
>
>
> char l_vcCadenaInicial[30] = "(RANCHO,
> ELKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFKSDKFSKDFKSKDFKSKDFK)";
> char l_vcSubCadenaDer[30]; // SubCadena después de la coma
> strcpy(l_vcSubCadenaDer, l_vcCadenaInicial + l_iPosicionArticulo);
>
> Si la cadena inicial fuera la anterior se produciría un desbordamiento


de
> pila, tecnica usada por algunos hacker para controlar el ordenador.
>
> Saludos
> Isidro
>
> "Willser F. González C." escribió en el mensaje
> news:
>> Cuántas comas (,) podría llegar a tener una cadena?; si es sólo una,
>> sería
>> que buscara la primer coma coincidente, esta búsqueda le devuelve la
>> posición donde la encontró, entonces, con base en esa posición se puede
>> sustraer la subcadena de la izquierda y la de la derecha, esas dos
>> subcadenas las concatena nuevamente pero en orden inverso y listo, ya
> está.
>> Claro que antes de hacer esta concatenación hay que hacer un ciclo para
> que
>> se determine si la segunda subcadena (la de la derecha) corresponde a


un
>> artículo.
>>
>> Algo así como:
>>
>> main()
>> {
>> char l_vvcArticulos[4][4] = {"EL", "LA", "LOS",


"LAS"};
>>
>> char l_vcCadenaInicial[30] = "(RANCHO, EL)";
>>
>> char l_vcSubCadenaDer[30]; // SubCadena después de la
> coma
>> (,).
>>
>> char l_vcCadenaFinal[30];
>>
>> char *l_pcPosicionComa = NULL;
>>
>> unsigned int i, l_iPosicionArticulo = 0;
>>
>>
>> l_pcPosicionComa = strchr(l_vcCadenaInicial, ','); // Buscar la


coma.
>>
>> l_iPosicionArticulo = l_pcPosicionComa - l_vcCadenaInicial + 2;
>>
>> if ((l_pcPosicionComa != NULL) &&
>> (l_iPosicionComa < strlen(l_vcCadenaInicial))) // Coma
>> encontrada.
>> {
>> strcpy(l_vcSubCadenaDer, l_vcCadenaInicial +
>> l_iPosicionArticulo);
>> // Extrae subcadena derecha.
>>
>> if (l_vcSubCadenaDer[strlen(l_vcSubCadenaDer) - 1] == ')') //
>> Eliminar el paréntesis.
>> {
>> l_vcSubCadenaDer[strlen(l_vcSubCadenaDer) - 1] = 0;
>>
>> _strupr(l_vcSubCadenaDer); // Convertir a mayúscula por si
>> acaso.
>> }
>>
>> for (i = 0; i < 4; i++) // Para cada artículo.
>> if (strcmp(l_vcSubCadenaDer, l_vvcArticulos[i]) == 0) // Es
>> un
>> artículo.
>> break;
>>
>> if (i < 4) // Es un artículo.
>> {
>> strcpy(l_vcCadenaFinal, "(");
>> strcat(l_vcCadenaFinal + 1, l_vcSubCadenaDer);
>> strcat(l_vcCadenaFinal, " ");
>> strncat(l_vcCadenaFinal, l_vcCadenaInicial + 1,
>> l_pcPosicionComa - l_vcCadenaInicial - 1);
>>
>> strcat(l_vcCadenaFinal, ")"); // Aquí queda la cadena
>> final
>> con el artículo al principio.
>> }
>> }
>> }
>>
>>
>> Willser F.
>>
>>
>>
>> "Arturo" escribió en el mensaje
>> news:006e01c59380$a4d5a910$
>> Hola a todos, espero que esten bien, en esta ocasion les
>> pido su ayuda para que me digan que instrucciones puedo
>> usar para alterar una cadena, los pongo el ejemplo de lo
>> que quiero:
>> char cadena[]="(RANCHO, EL)"
>> Esto al final debe quedar: char cadena[]="(EL RANCHO)"
>> pero solamente debe ocurrir cuando las palabras despues de
>> la coma sea: EL, LOS, LA, LAS. En caso de que yo envie:
>> (TECOLOTES, EJIDO CAMPECHE) no debe hacer nada; en si
>> siempre que haya un articulo despues de la coma lo haga,
>> ¿Me pueden decir como le hago por favor? Si tiene un
>> codigo mejor porque apenas estoy aprendiendo C++. De
>> antemano muchas gracias anticipadas.
>>
>>
>>
>
>
>



email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida