¿Cómo tokenizo una cadena en C++?

8 minutos de lectura

¿Como tokenizo una cadena en C
Bill el lagarto

Java tiene un método de división conveniente:

String str = "The quick brown fox";
String[] results = str.split(" ");

¿Hay una manera fácil de hacer esto en C++?

  • No puedo creer que esta tarea rutinaria sea un dolor de cabeza en C++

    – wfbarksdale

    8 de septiembre de 2011 a las 5:05

  • No es un dolor de cabeza en c ++, hay varias formas de lograrlo. los programadores son menos conscientes de c ++ que de c #; se trata de marketing e inversiones … vea esto para varias opciones de c ++ para lograr lo mismo: cplusplus.com/faq/secuencias/cadenas/split

    – hB0

    31 de octubre de 2013 a las 0:10


  • @ hB0 pasar por muchas preguntas y respuestas y aún no decidir los medios es un dolor de cabeza. el uno necesita esa biblioteca, el otro es solo para espacios, el otro no maneja espacios …

    – Paschalis

    14/04/2016 a las 17:02

  • ¿Posible duplicado de Dividir una cadena en C++?

    – KOB

    8 mayo 2017 a las 19:16

  • ¿Por qué todo en C++ tiene que ser una lucha?

    –Wael Assaf

    13 de agosto de 2019 a las 10:26


¿Como tokenizo una cadena en C
Adán Pierce

Aquí hay uno realmente simple:

#include <vector>
#include <string>
using namespace std;

vector<string> split(const char *str, char c=" ")
{
    vector<string> result;

    do
    {
        const char *begin = str;

        while(*str != c && *str)
            str++;

        result.push_back(string(begin, str));
    } while (0 != *str++);

    return result;
}

  • ¿Necesito agregar un prototipo para este método en el archivo .h?

    – Suhrob Samiev

    22 de diciembre de 2011 a las 8:26


  • Esta no es exactamente la “mejor” respuesta, ya que todavía usa un literal de cadena que es la matriz de caracteres constante C simple. Creo que el interrogador estaba preguntando si podía tokenizar una cadena C ++ que es del tipo “cadena” introducida por este último.

    – Vijay Kumar Kanta

    19 de abril de 2017 a las 7:05

  • Esto necesita una nueva respuesta porque sospecho firmemente que la inclusión de expresiones regulares en C++ 11 ha cambiado cuál sería la mejor respuesta.

    – Omnifaro

    25/10/2017 a las 15:45

  • Para esta respuesta, tengo un problema con las cadenas en las que el primer/último carácter es igual al separador. por ejemplo, la cadena “a” da como resultado [” “, “a”].

    – y30

    13 de noviembre de 2020 a las 11:26


  • Lamentablemente, boost no siempre está disponible para todos los proyectos. Tendré que buscar una respuesta que no sea de impulso.

    – Pantuflas FuzzyBunny

    20 dic 2013 a las 21:00

  • No todos los proyectos están abiertos al “código abierto”. Trabajo en industrias fuertemente reguladas. No es un problema, de verdad. Es solo un hecho de la vida. Boost no está disponible en todas partes.

    – Pantuflas FuzzyBunny

    20 de diciembre de 2013 a las 23:19

  • @NonlinearIdeas La otra pregunta / respuesta no se trataba en absoluto de proyectos de código abierto. Lo mismo es cierto para ninguna proyecto. Dicho esto, por supuesto entiendo los estándares restringidos como MISRA C, pero luego se entiende que de todos modos construyes todo desde cero (a menos que encuentres una biblioteca compatible, una rareza). De todos modos, el punto no es que “Boost no está disponible” – es que tiene requisitos especiales para los cuales casi ninguna respuesta de propósito general sería inadecuado.

    – Konrad Rodolfo

    21 de diciembre de 2013 a las 10:46

  • @NonlinearIdeas Por ejemplo, las otras respuestas que no son de Boost tampoco cumplen con MISRA.

    – Konrad Rodolfo

    21 de diciembre de 2013 a las 10:47

  • @Dmitry ¿Qué es “vomitar STL”? Y toda la comunidad está muy a favor de reemplazar el preprocesador C; de hecho, hay propuestas para hacerlo. Pero su sugerencia de usar PHP o algún otro lenguaje en su lugar sería un gran paso atrás.

    – Konrad Rodolfo

    11/09/2016 a las 17:43

1647642614 532 ¿Como tokenizo una cadena en C
usuario35978

Otra forma rápida es usar getline. Algo como:

stringstream ss("bla bla");
string s;

while (getline(ss, s, ' ')) {
 cout << s << endl;
}

Si quieres, puedes hacer un sencillo split() método que devuelve un vector<string>que es realmente útil.

  • Tuve problemas al usar esta técnica con caracteres 0x0A en la cadena, lo que hizo que el ciclo while se cerrara prematuramente. De lo contrario, es una buena solución simple y rápida.

    –Ryan H.

    24/01/2011 a las 23:00


  • Esto es bueno, pero debe tener en cuenta que al hacer esto, el delimitador predeterminado ‘\n’ no se considera. Este ejemplo funcionará, pero si está usando algo como: while(getline(inFile,word,’ ‘)) where inFile es un objeto ifstream que contiene varias líneas, obtendrá resultados divertidos.

    – hack rock

    19 de junio de 2012 a las 21:28

  • es una lástima que getline devuelva el flujo en lugar de la cadena, lo que lo hace inutilizable en las listas de inicialización sin almacenamiento temporal

    – Fuzzy Tew

    3 de agosto de 2013 a las 12:34

  • ¡Frio! Sin impulso y C ++ 11, ¡una buena solución para los proyectos heredados que existen!

    – Deqing

    30 de abril de 2014 a las 7:09

  • ESA es la respuesta, el nombre de la función es un poco incómodo.

    – ceros

    1 jun 2019 a las 21:31

1647642615 759 ¿Como tokenizo una cadena en C
marca

Usa strtok. En mi opinión, no es necesario crear una clase en torno a la tokenización a menos que strtok no le proporcione lo que necesita. Puede que no, pero en más de 15 años escribiendo varios códigos de análisis en C y C++, siempre he usado strtok. Aquí hay un ejemplo

char myString[] = "The quick brown fox";
char *p = strtok(myString, " ");
while (p) {
    printf ("Token: %s\n", p);
    p = strtok(NULL, " ");
}

Algunas advertencias (que pueden no satisfacer sus necesidades). La cadena se “destruye” en el proceso, lo que significa que los caracteres EOS se colocan en línea en los puntos delimitadores. El uso correcto puede requerir que haga una versión no constante de la cadena. También puede cambiar la lista de delimitadores a mitad del análisis.

En mi opinión, el código anterior es mucho más simple y fácil de usar que escribir una clase separada para él. Para mí, esta es una de esas funciones que brinda el lenguaje y lo hace bien y limpio. Es simplemente una solución “basada en C”. Es apropiado, es fácil y no tienes que escribir mucho código extra 🙂

  • Tuve problemas al usar esta técnica con caracteres 0x0A en la cadena, lo que hizo que el ciclo while se cerrara prematuramente. De lo contrario, es una buena solución simple y rápida.

    –Ryan H.

    24/01/2011 a las 23:00


  • Esto es bueno, pero debe tener en cuenta que al hacer esto, el delimitador predeterminado ‘\n’ no se considera. Este ejemplo funcionará, pero si está usando algo como: while(getline(inFile,word,’ ‘)) where inFile es un objeto ifstream que contiene varias líneas, obtendrá resultados divertidos.

    – hack rock

    19 de junio de 2012 a las 21:28

  • es una lástima que getline devuelva el flujo en lugar de la cadena, lo que lo hace inutilizable en las listas de inicialización sin almacenamiento temporal

    – Fuzzy Tew

    3 de agosto de 2013 a las 12:34

  • ¡Frio! Sin impulso y C ++ 11, ¡una buena solución para los proyectos heredados que existen!

    – Deqing

    30 de abril de 2014 a las 7:09

  • ESA es la respuesta, el nombre de la función es un poco incómodo.

    – ceros

    1 jun 2019 a las 21:31

1647642615 785 ¿Como tokenizo una cadena en C
keithb

Puede usar secuencias, iteradores y el algoritmo de copia para hacer esto de manera bastante directa.

#include <string>
#include <vector>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>
#include <sstream>
#include <algorithm>

int main()
{
  std::string str = "The quick brown fox";

  // construct a stream from the string
  std::stringstream strstr(str);

  // use stream iterators to copy the stream to the vector as whitespace separated strings
  std::istream_iterator<std::string> it(strstr);
  std::istream_iterator<std::string> end;
  std::vector<std::string> results(it, end);

  // send the vector to stdout.
  std::ostream_iterator<std::string> oit(std::cout);
  std::copy(results.begin(), results.end(), oit);
}

  • Encuentro esos std:: irritantes de leer… ¿por qué no usar “using”?

    – usuario35978

    28 de noviembre de 2008 a las 4:19

  • @Vadi: porque editar la publicación de otra persona es bastante intrusivo. @pheze: prefiero dejar que el std así sé de dónde viene mi objeto, eso es meramente una cuestión de estilo.

    – Matthieu M.

    2 de abril de 2010 a las 8:49

  • Entiendo su razón y creo que en realidad es una buena opción si funciona para usted, pero desde un punto de vista pedagógico estoy de acuerdo con pheze. Es más fácil leer y comprender un ejemplo completamente extraño como este con un “usando espacio de nombres estándar” en la parte superior porque requiere menos esfuerzo para interpretar las siguientes líneas… especialmente en este caso porque todo es de la biblioteca estándar. Puede hacer que sea fácil de leer y obvio de dónde provienen los objetos mediante una serie de “usando std::string;” etc. Especialmente porque la función es tan corta.

    – Cheshirekow

    16 de julio de 2010 a las 11:27

  • A pesar de que los prefijos “std::” son irritantes o feos, es mejor incluirlos en el código de ejemplo para que quede completamente claro de dónde provienen estas funciones. Si te molestan, es trivial reemplazarlos con un “uso” después de que robes el ejemplo y lo reclames como tuyo.

    – dlcámaras

    11 de abril de 2012 a las 14:54

  • ¡sí! ¡lo que dijo! mejores prácticas es utilizar el prefijo std. Sin duda, cualquier base de código grande tendrá sus propias bibliotecas y espacios de nombres, y usar “usar espacio de nombres estándar” le dará dolores de cabeza cuando comience a causar conflictos de espacios de nombres.

    – Miek

    18 de julio de 2012 a las 17:08

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad