En este post te enseñaré cómo separar una cadena por delimitador o token (una coma, espacios, punto y coma, saltos de línea, puntos) en C++. Esto se conoce en varios lenguajes como la función split, aunque en C++ no existe esa función pero podemos llegar al mismo resultado.
Con lo que te enseñaré hoy podrás separar una cadena por comas, punto y coma, etecétera usando el lenguaje C++ también conocido como CPP. Recuerda que puedes hacerlo con strtok usando C, pero hoy te enseñaré otro enfoque que funciona en C++.
Sobre getline
La función getline
recibe un stream de entrada, la cadena de destino y un delimitador. Básicamente lee caracteres del stream dentro de la cadena hasta que alcanza el delimitador.
Normalmente usamos getline
para leer archivos de texto línea por línea (el delimitador es \n
), pero los streams sirven para más cosas.
En este caso podemos usar getline
para crear nuestra propia función split, convirtiendo nuestra cadena a un stream de entrada y usando getline
para leer cada token por separado.
Ejemplo C++: separar cadena por punto y coma
Ya hablé mucho; vamos al código. En este ejemplo vamos a separar una cadena usando CPP y el delimitador será el punto y coma.
Primero definimos la cadena temporal en donde vamos a ir almacenando, en cada lectura, a la cadena separada. También definimos la cadena que vamos a separar y el stream al que será convertido la cadena.
/*
https://parzibyte.me/blog
*/
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
string lectura; // Aquí vamos a ir leyendo cada valor por separado
string cadena = "soy;una cadena;separada por punto y coma"; // La cadena que vamos a separar
stringstream input_stringstream(cadena); // Convertir la cadena a un stream
while (getline(input_stringstream, lectura, ';'))
{
cout << "Un valor: " << lectura << endl;
}
}
Después vamos invocando a getline mientras la misma todavía pueda leer; por eso es que está dentro de un while
. En cada lectura, getline va a leer de la cadena usando ese delimitador y lo va a ir almacenando dentro de lectura.
Fíjate en que el delimitador es un carácter que pasamos como tercer argumento a la función getline, y de este modo es como separamos la cadena en C++. Al ejecutarlo, la salida es:
Como puedes ver, funciona perfectamente. Ahora veamos otro enfoque.
Llamadas separadas a getline
En el ejemplo anterior leímos la cadena y la fuimos separando hasta que la misma “se consumió”, pero puede darse el caso de que sepamos la cantidad de tokens que contiene desde antes y necesitemos leerlos como arreglo, convirtiendo la cadena a algo así como un arreglo en C++.
Por ejemplo, si tenemos una cadena de un archivo CSV que siempre tiene las mismas columnas podemos llamar a getline
determinadas veces en lugar de usar while
. Veamos el siguiente ejemplo:
/*
https://parzibyte.me/blog
*/
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
string cadena = "Luis;Cabrera;luis@ejemplo.com;parzibyte.me"; // Nombre;Apellido;correo;página web
stringstream input_stringstream(cadena); // Convertir la cadena a un stream
string nombre, apellido, correo, paginaWeb;
// Extraer
getline(input_stringstream, nombre, ';');
getline(input_stringstream, apellido, ';');
getline(input_stringstream, correo, ';');
getline(input_stringstream, paginaWeb, ';');
// Imprimir
cout << "Nombre: " << nombre << endl;
cout << "Apellido: " << apellido << endl;
cout << "Correo: " << correo << endl;
cout << "Web: " << paginaWeb << endl;
}
El código es casi el mismo, pero ahora llamamos a getline
4 veces, pues sabemos que tenemos 4 columnas de datos en tiempo de compilación, de modo que confiamos en que los valores van a estar presentes, por eso es que tampoco verificamos si la llamada a getline
fue exitosa.
Con esto ya puedes separar cualquier tipo de texto, solo debes convertir la cadena a un stream y leer de ella con getline
usando C++.
Último ejemplo
Solo para complementar el post, veamos cómo separar la misma cadena pero ahora separada por espacios. El código queda casi igual, excepto por el delimitador.
Por cierto, si quisieras separarlo por líneas usarías a \n
como delimitador.
/*
https://parzibyte.me/blog
*/
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
string cadena = "Luis Cabrera luis@ejemplo.com parzibyte.me"; // Nombre Apellido correo página web
stringstream input_stringstream(cadena); // Convertir la cadena a un stream
string nombre, apellido, correo, paginaWeb;
// Extraer
char delimitador =' ';
getline(input_stringstream, nombre, delimitador);
getline(input_stringstream, apellido, delimitador);
getline(input_stringstream, correo, delimitador);
getline(input_stringstream, paginaWeb, delimitador);
// Imprimir
cout << "Nombre: " << nombre << endl;
cout << "Apellido: " << apellido << endl;
cout << "Correo: " << correo << endl;
cout << "Web: " << paginaWeb << endl;
}
Cuando yo lo ejecuto, la salida es correcta:
Para terminar te dejo con más programas de C++ en mi blog.