usar resueltos matriz leer funciones ejercicios ejemplos como caracteres cadenas cadena arreglo c++ parsing split

resueltos - Analizar(dividir) una cadena en C++ usando un delimitador de cadena(C++ estándar)



leer cadena de caracteres en c (11)

Para delimitador de cuerdas

Cadena dividida basada en un delimitador de cadena . Como dividir la cadena "adsf-+qwret-+nvfkbdsj-+orthdfjgh-+dfjrleih" basado en delimitador de cadena "-+" , la salida será {"adsf", "qwret", "nvfkbdsj", "orthdfjgh", "dfjrleih"}

#include <iostream> #include <sstream> #include <vector> using namespace std; // for string delimiter vector<string> split (string s, string delimiter) { size_t pos_start = 0, pos_end, delim_len = delimiter.length(); string token; vector<string> res; while ((pos_end = s.find (delimiter, pos_start)) != string::npos) { token = s.substr (pos_start, pos_end - pos_start); pos_start = pos_end + delim_len; res.push_back (token); } res.push_back (s.substr (pos_start)); return res; } int main() { string str = "adsf-+qwret-+nvfkbdsj-+orthdfjgh-+dfjrleih"; string delimiter = "-+"; vector<string> v = split (str, delimiter); for (auto i : v) cout << i << endl; return 0; }


Salida

adsf qwret nvfkbdsj orthdfjgh dfjrleih




Para delimitador de un solo carácter.

Cadena dividida basada en un delimitador de caracteres. Como dividir la cadena "adsf+qwer+poui+fdgh" con el delimitador "+" dará como resultado {"adsf", "qwer", "poui", "fdg"h}

#include <iostream> #include <sstream> #include <vector> using namespace std; vector<string> split (const string &s, char delim) { vector<string> result; stringstream ss (s); string item; while (getline (ss, item, delim)) { result.push_back (item); } return result; } int main() { string str = "adsf+qwer+poui+fdgh"; vector<string> v = split (str, ''+''); for (auto i : v) cout << i << endl; return 0; }


Salida

adsf qwer poui fdgh

Esta pregunta ya tiene una respuesta aquí:

Estoy analizando una cadena en C ++ usando lo siguiente:

string parsed,input="text to be parsed"; stringstream input_stringstream(input); if(getline(input_stringstream,parsed,'' '')) { // do some processing. }

El análisis con un solo delimitador de caracteres está bien. Pero qué pasa si quiero usar una cadena como delimitador.

Ejemplo: quiero dividir:

scott>=tiger

con> = como delimitador para que pueda obtener scott y tiger.


Aquí está mi opinión sobre esto. Maneja los casos de borde y toma un parámetro opcional para eliminar entradas vacías de los resultados.

bool endsWith(const std::string& s, const std::string& suffix) { return s.size() >= suffix.size() && s.substr(s.size() - suffix.size()) == suffix; } std::vector<std::string> split(const std::string& s, const std::string& delimiter, const bool& removeEmptyEntries = false) { std::vector<std::string> tokens; for (size_t start = 0, end; start < s.length(); start = end + delimiter.length()) { size_t position = s.find(delimiter, start); end = position != string::npos ? position : s.length(); std::string token = s.substr(start, end - start); if (!removeEmptyEntries || !token.empty()) { tokens.push_back(token); } } if (!removeEmptyEntries && (s.empty() || endsWith(s, delimiter))) { tokens.push_back(""); } return tokens; }

Ejemplos

split("a-b-c", "-"); // [3]("a","b","c") split("a--c", "-"); // [3]("a","","c") split("-b-", "-"); // [3]("","b","") split("--c--", "-"); // [5]("","","c","","") split("--c--", "-", true); // [1]("c") split("a", "-"); // [1]("a") split("", "-"); // [1]("") split("", "-", true); // [0]()


Este código divide líneas del texto y agrega a todos a un vector.

vector<string> split(char *phrase, string delimiter){ vector<string> list; string s = string(phrase); size_t pos = 0; string token; while ((pos = s.find(delimiter)) != string::npos) { token = s.substr(0, pos); list.push_back(token); s.erase(0, pos + delimiter.length()); } list.push_back(s); return list; }

Llamado por:

vector<string> listFilesMax = split(buffer, "/n");


Este método utiliza std::string::find sin mutar la cadena original al recordar el principio y el final del token de subcadena anterior.

#include <iostream> #include <string> int main() { std::string s = "scott>=tiger"; std::string delim = ">="; auto start = 0U; auto end = s.find(delim); while (end != std::string::npos) { std::cout << s.substr(start, end - start) << std::endl; start = end + delim.length(); end = s.find(delim, start); } std::cout << s.substr(start, end); }


Puede usar la función std::string::find() para encontrar la posición de su delimitador de cadena, luego use std::string::substr() para obtener un token.

Ejemplo:

std::string s = "scott>=tiger"; std::string delimiter = ">="; std::string token = s.substr(0, s.find(delimiter)); // token is "scott"

  • La función find(const string& str, size_t pos = 0) devuelve la posición de la primera aparición de str en la cadena, o npos si no se encuentra la cadena.

  • La función substr(size_t pos = 0, size_t n = npos) devuelve una subcadena del objeto, comenzando en la posición pos y de la longitud npos .

Si tiene varios delimitadores, después de haber extraído un token, puede eliminarlo (incluido el delimitador) para continuar con las extracciones posteriores (si desea conservar la cadena original, solo use s = s.substr(pos + delimiter.length()); ):

s.erase(0, s.find(delimiter) + delimiter.length());

De esta manera puede hacer un bucle fácilmente para obtener cada token.

Ejemplo completo

std::string s = "scott>=tiger>=mushroom"; std::string delimiter = ">="; size_t pos = 0; std::string token; while ((pos = s.find(delimiter)) != std::string::npos) { token = s.substr(0, pos); std::cout << token << std::endl; s.erase(0, pos + delimiter.length()); } std::cout << s << std::endl;

Salida:

scott tiger mushroom


Puedes usar la siguiente función para dividir la cadena:

vector<string> split(const string& str, const string& delim) { vector<string> tokens; size_t prev = 0, pos = 0; do { pos = str.find(delim, prev); if (pos == string::npos) pos = str.length(); string token = str.substr(prev, pos-prev); if (!token.empty()) tokens.push_back(token); prev = pos + delim.length(); } while (pos < str.length() && prev < str.length()); return tokens; }


Si no desea modificar la cadena (como en la respuesta de Vincenzo Pii) y desea enviar también el último token, puede usar este método:

inline std::vector<std::string> splitString( const std::string &s, const std::string &delimiter ){ std::vector<std::string> ret; size_t start = 0; size_t end = 0; size_t len = 0; std::string token; do{ end = s.find(delimiter,start); len = end - start; token = s.substr(start, len); ret.emplace_back( token ); start += len + delimiter.length(); std::cout << token << std::endl; }while ( end != std::string::npos ); return ret; }


Yo usaría boost::tokenizer . Aquí hay documentación que explica cómo realizar una función de tokenizer adecuada: http://www.boost.org/doc/libs/1_52_0/libs/tokenizer/tokenizerfunction.htm

Aquí hay uno que funciona para su caso.

struct my_tokenizer_func { template<typename It> bool operator()(It& next, It end, std::string & tok) { if (next == end) return false; char const * del = ">="; auto pos = std::search(next, end, del, del + 2); tok.assign(next, pos); next = pos; if (next != end) std::advance(next, 2); return true; } void reset() {} }; int main() { std::string to_be_parsed = "1) one>=2) two>=3) three>=4) four"; for (auto i : boost::tokenizer<my_tokenizer_func>(to_be_parsed)) std::cout << i << ''/n''; }


strtok te permite pasar múltiples caracteres como delimitadores. Apuesto a que si pasaste "> =" tu cadena de ejemplo se dividiría correctamente (aunque> y = se cuentan como delimitadores individuales).

EDITAR si no desea usar c_str() para convertir de cadena a char *, puede usar substr y find_first_of para tokenizar.

string token, mystring("scott>=tiger"); while(token != mystring){ token = mystring.substr(0,mystring.find_first_of(">=")); mystring = mystring.substr(mystring.find_first_of(">=") + 1); printf("%s ",token.c_str()); }


#include<iostream> #include<algorithm> using namespace std; int split_count(string str,char delimit){ return count(str.begin(),str.end(),delimit); } void split(string str,char delimit,string res[]){ int a=0,i=0; while(a<str.size()){ res[i]=str.substr(a,str.find(delimit)); a+=res[i].size()+1; i++; } } int main(){ string a="abc.xyz.mno.def"; int x=split_count(a,''.'')+1; string res[x]; split(a,''.'',res); for(int i=0;i<x;i++) cout<<res[i]<<endl; return 0; }

PS: funciona solo si las longitudes de las cadenas después de la división son iguales


std::vector<std::string> split(const std::string& s, char c) { std::vector<std::string> v; unsigned int ii = 0; unsigned int j = s.find(c); while (j < s.length()) { v.push_back(s.substr(i, j - i)); i = ++j; j = s.find(c, j); if (j >= s.length()) { v.push_back(s.substr(i, s,length())); break; } } return v; }