Tema destacado: Personaliza-Escoge el diseño del foro que más te guste.
Autor
|
Tema: [Source] Split en C++ 100% funcional (Leído 5,790 veces)
|
|
~~
|
Hola: Aki os dejo como aporte la funcion Split para C++. Esta funcion imita a la de VB y vale para obtener un trozo de cadena separandola por un carater determinado. Lo mejor es q la proveis vosotros mismos: #include <iostream> #include <string>
std::string Split(std::string cadena, char m, int numero);
int cuenta; //Determina el espacio del Buffer en el q escribimos int posicion; //Determina la posición del caracter por donde keremos partir
int main() { std::string entrada; char caracter; int numero;
std::cout << "Introduzca la cadena --> "; std::cin >> entrada; std::cout << "Introduzca el caracter --> "; std::cin >> caracter; std::cout << "Introduzca el numero --> "; std::cin >> numero; std::string Recibido; Recibido = Split(entrada,caracter, numero); std::cout << Recibido; return 0; }
std::string Split (std::string cadena, char m, int numero) { posicion = cadena.find (m);
if (posicion != -1) //Si se encuentra el caracter deseado { std::string principal (cadena.substr (0,posicion)); //Guardamos el primer trozo de cadena std::string secundaria (cadena.substr (posicion + 1,cadena.length ())); //Guardamos el resto de la cadena if (cuenta == numero) { std::string Cadena; Cadena = principal; return Cadena; } cuenta++; Split (secundaria,m,numero); }else{ return cadena; //Si no encontramos el caracter deseado devolvemos la cadena entera }
} Espero q os sea util por q sus kebraderos de cabeza me a costado, aunke luego la solucion era facil xDD 1S4ludo y gracias a los q por lo menos me han intentado ayudar 
|
|
|
|
« Última modificación: 9 Septiembre 2009, 23:53 por E0N »
|
En línea
|
|
|
|
|
~~
|
Aclaro un poco la parte q no me sale por q parece q no se entiende. Pretendo hacer ersto: #include <iostream> #include <string>
std::string *Split(std::string cadena, char m);
std::string Buffer [250];//El Buffer de cadenas int cuenta; //Determina el espacio del Buffer en el q escribimos int posicion; //Determina la posición del caracter por donde keremos partir
int main() { std::string entrada; char caracter;
std::cout << "Introduzca la cadena --> "; std::cin >> entrada; std::cout << "Introduzca el caracter --> "; std::cin >> caracter;
//Si intentamos mostrar el resultado de cualkiera de estas dos maneras aparecen simbolos raros ¿?¿? std::string* devuelta = Split (entrada,caracter); std::cout << *devuelta << '\n';
std::cout << *Split(entrada,caracter) << '\n'; return 0; }
std::string *Split (std::string cadena, char m) { posicion = cadena.find (m);
if (posicion != -1) //Si se encuentra el caracter deseado { std::string principal (cadena.substr (0,posicion)); //Guardamos el primer trozo de cadena std::string secundaria (cadena.substr (posicion + 1,cadena.length ())); //Guardamos el resto de la cadena
Buffer [cuenta] = principal; cuenta++;
Split (secundaria,m);
}else{ //Si no se encuentra salimos Buffer[cuenta] = cadena; static std::string *Retorno = new std::string[cuenta+2]; //Creamos una matriz con lo espacios justos q keremos debolver for (int h=0; h <= cuenta; h++) //Asignamos los valores q nos interesan { Retorno[h] = Buffer[h]; } cuenta = 0; //Ponemos la cuenta a cero para porder seguir usando la función std::cout << "La cadena bien devuelta seria: " << Retorno[0] << '\n';//Aki vemos como lo q se va a devolver es correcto return &Retorno[0]; } } Si ponemos en la entrada "Hola|mundo" y q lo parta por el '|' nos deberia devolver: devuelta[0] = Hola devuelta[1] = mundo Pero no lo hace, lo curioso es q si pongo "Hola" y busco '|' por ejemplo, evidentemente no lo encuentra y lo curioso es q me devuelve todo bien ¿??¿? y estoy usando metodos de devolucion q con una matriz de enteros por ejemplo funcionan bien... q raro no?? Os pongo dos salidas de consola para q veais al lo q me refiero: Para q encuentre el caracter deseado: Introduzca la cadena --> Hola|mundo Introduzca el caracter --> | La cadena bien devuelta seria: Hola âPÞQ· âj èUÓRâý►ï╠ëeðìEõPÞÊ· ëE└Þz· ─¶ëE╝ïM╝Qh╚èG La cadena bien devuelta seria: Hola └ ↕ Simbolos raros  Pero si ponemos para q no encuentre en caracter deseado: Introduzca la cadena --> Hola|mundo Introduzca el caracter --> 1 La cadena bien devuelta seria: Hola|mundo Hola|mundo La cadena bien devuelta seria: Hola|mundo Hola|mundo Lo devuelve perfewctamente  Alguien sabe por q puede ser??
|
|
|
|
|
En línea
|
|
|
|
clascrip
Desconectado
Mensajes: 9
|
Hola EON, el fallo esta en que la direccion de la matriz dinámica se pierde por el camino  . En en else, haces un return &Retorno[0]; pero si la función se había llamada alguna vez a sí misma, después de esta llamada vas a parar a: Split (secundaria,m); Si te fijas en esta parte del código, no guardas la dirección que devuelve la función en ninguna variable y al finalizar todas las llamadas que se ha hecho la función a sí misma, la función no devuelve nada. Para solucionarlo puedes declarar el puntero Retorno al principio de la función y asignarle NULL. Además tendrías que guardar en Retorno el resultado de la llamada a: Split (secundaria,m); Y has de poner la sentencia: return &Retorno[0]; fuera del else. Aparte de esto, algunos detalles más: Esto: return &Retorno[0]; Equivale a: return Retorno; static std::string *Retorno = new std::string[cuenta+2]; No entiendo porque lo pones como static ni porque pones cuenta + 2. Yo creo que no hace falta el static y que solo tienes que poner cuenta + 1 (porque el primer indice es el 0, en vez del 1 y entonces hay un elemento más que el número del último indice). Aparte de eso, reservas memoria con new pero no la liberas, antes del return 0 deberías liberar la memoria que has reservado. Lo puedes hacer asi: delete devuelta; Por ultimo, con esto: std::cout << *devuelta << '\n'; Solo muestras la primera subcadena, para mostrarlas todas tendrías que saber cuantas subcadenas hay y utilizar un bucle: for(int i = 0; i < n; i++) { std::cout << devuelta[i]<< '\n'; }
Donde n es el número de subcadenas. Bueno, espero haberme explicado. Saludos.
|
|
|
|
|
En línea
|
|
|
|
Rozor
Desconectado
Mensajes: 269
As I Walk Through The Valley Of The Shadow Of Dead
|
Ami me funciona bien compilado en Visual Studio 6.0 SP6 , en modo Debug o Release Introduzca la cadena --> hola|mundo Introduzca el caracter --> 1 hola|mundo Press any key to continue
|
|
|
|
|
En línea
|
out in the streets they call it murder....
|
|
|
|
~~
|
Ami me funciona bien compilado en Visual Studio 6.0 SP6 , en modo Debug o Release Introduzca la cadena --> hola|mundo Introduzca el caracter --> 1 hola|mundo Press any key to continue
Si te devuelve eso es q no funciona bien xDD Tendria q ponerte: Introduzca la cadena --> hola|mundo Introduzca el caracter --> | hola Ya puse arriba q si no encontraba el caracter (como pone en tu ej) funcionaba bien. Hola EON, el fallo esta en que la direccion de la matriz dinámica se pierde por el camino  . En en else, haces un return &Retorno[0]; pero si la función se había llamada alguna vez a sí misma, después de esta llamada vas a parar a: Split (secundaria,m); Si te fijas en esta parte del código, no guardas la dirección que devuelve la función en ninguna variable y al finalizar todas las llamadas que se ha hecho la función a sí misma, la función no devuelve nada. Para solucionarlo puedes declarar el puntero Retorno al principio de la función y asignarle NULL. Además tendrías que guardar en Retorno el resultado de la llamada a: Split (secundaria,m); Y has de poner la sentencia: return &Retorno[0]; fuera del else. No se pierde por el camino, ya q la voy guardando en el Buffer, q es externo a la funcion. return &Retorno[0]; Equivale a: return Retorno; Lo se pero me gusta mas usar la de arriba, por q representa mejor el caracter matricial. static std::string *Retorno = new std::string[cuenta+2]; No entiendo porque lo pones como static ni porque pones cuenta + 2. Yo creo que no hace falta el static y que solo tienes que poner cuenta + 1 (porque el primer indice es el 0, en vez del 1 y entonces hay un elemento más que el número del último indice) Ahí tienes razon  pero como ya no me funcionaba keria provar todas las posibilidades antes de preguntar, a ver si era por eso y al final lo posteé asi xDD Aparte de eso, reservas memoria con new pero no la liberas, antes del return 0 deberías liberar la memoria que has reservado. Lo puedes hacer asi: delete devuelta; Sip, pero es q si la borro no la devolveria no?? Por ultimo, con esto: Código: std::cout << *devuelta << '\n'; Solo muestras la primera subcadena, para mostrarlas todas tendrías que saber cuantas subcadenas hay y utilizar un bucle: Código: for(int i = 0; i < n; i++) { std::cout << devuelta << '\n'; }
Donde n es el número de subcadenas.
Bueno, espero haberme explicado. Saludos.Ya, era solo para provar q devolvia bien y ya ni el primero devuelve bien...
Weno q al final ya se como hacerlo funcionar xDD solo hay q añadir un parametro mas por ej Split ("Cadena|a|partir,'|',0) asi no devolveria cadna q es la primera de las partes (de ahí el 0) asi es facil llamarse solamete las veces necesarias y q devuelva lo q interesa, pero de todas formas gracias por la ayuda  1S4ludo
|
|
|
|
|
En línea
|
|
|
|
clascrip
Desconectado
Mensajes: 9
|
Mira te pongo el código con las correciones que hice a ver que te parece: #include <iostream> #include <string>
std::string *Split(std::string cadena, char m);
std::string Buffer [250];//El Buffer de cadenas int cuenta; //Determina el espacio del Buffer en el q escribimos int posicion; //Determina la posición del caracter por donde keremos partir
int main() { std::string entrada; char caracter; std::cout << "Introduzca la cadena --> "; std::cin >> entrada; std::cout << "Introduzca el caracter --> "; std::cin >> caracter;
std::string* devuelta = Split (entrada,caracter); delete devuelta;
return 0; }
std::string *Split (std::string cadena, char m) { posicion = cadena.find (m); std::string *Retorno = NULL;
if (posicion != -1) //Si se encuentra el caracter deseado { std::string principal (cadena.substr (0,posicion)); //Guardamos el primer trozo de cadena std::string secundaria (cadena.substr (posicion + 1,cadena.length ())); //Guardamos el resto de la cadena
Buffer [cuenta] = principal; cuenta++;
Retorno = Split (secundaria,m);
}else { Buffer[cuenta] = cadena; Retorno = new std::string[cuenta+1]; //Creamos una matriz con lo espacios justos q keremos debolver for (int h=0; h <= cuenta; h++) //Asignamos los valores q nos interesan { Retorno[h] = Buffer[h]; std::cout << Retorno[h] << '\n'; } cuenta = 0; } return Retorno; }
PD: Más vale un código que mil explicaciones  .
|
|
|
|
|
En línea
|
|
|
|
|
~~
|
Pues a mi no me funciona clascrip... en medio de la ejecucion me sale un error de esos de q a sucedido un problema bla, bla bla...
Mirad e creado este q deberia funcionar pero de nuevo no devuelve bien, a ver si le veis el fallo:
EDITADO: Ver el de abajo
|
|
|
|
« Última modificación: 14 Enero 2007, 17:26 por E0N »
|
En línea
|
|
|
|
|
~~
|
Hola de nuevo  A ver el code de antes es un poco lioso y no es necesario, este es el weno: #include <iostream> #include <string>
std::string Split(std::string cadena, char m, int numero);
std::string Buffer [250];//El Buffer de cadenas int cuenta; //Determina el espacio del Buffer en el q escribimos int posicion; //Determina la posición del caracter por donde keremos partir
int main() { std::string entrada; char caracter; int numero;
std::cout << "Introduzca la cadena --> "; std::cin >> entrada; std::cout << "Introduzca el caracter --> "; std::cin >> caracter; std::cout << "Introduzca el numero --> "; std::cin >> numero; std::string Recibido; Recibido = Split(entrada,caracter, numero); std::cout << Recibido; return 0; }
std::string Split (std::string cadena, char m, int numero) { posicion = cadena.find (m);
if (posicion != -1) //Si se encuentra el caracter deseado { std::string principal (cadena.substr (0,posicion)); //Guardamos el primer trozo de cadena std::string secundaria (cadena.substr (posicion + 1,cadena.length ())); //Guardamos el resto de la cadena
Buffer [cuenta] = principal; cuenta++;
Split (secundaria,m,numero);
}else{ //Si no se encuentra salimos Buffer[cuenta] = cadena; std::string Cadena; Cadena = Buffer[numero]; std::cout << Cadena << '\n'; //Vemos como deberia devolver bien
return Cadena; } } Sin embargo al ejecutar el programa me salta un error de esos de q se a de cerrar y si quiero enviar los errores... Si le doi al debug me aparece "Unhandled exception in Split.exe: 0xC0000005: Acces Violation" Alguien sabe por q sucede esto o por lo menos q sucede?? Gracias  1S4ludo
|
|
|
|
|
En línea
|
|
|
|
|
~~
|
Vale, me siento estupido contestndome a mi mismo... al final era mas facil de lo q creia, ya tengo la funcion, esta en el primer post
1S4ludo
|
|
|
|
|
En línea
|
|
|
|
|
|