sume suma reste resta que programa para operaciones numeros multiplique multiplicar multiplicacion divida basicas c++ stl std

suma - Una forma sencilla de dividir una secuencia de cadenas separadas por nulos en C++



programa que sume reste multiplique y divida en c++ (7)

Tengo una serie de cadenas almacenadas en una sola matriz, separadas por nulos (por ejemplo, [''f'', ''o'', ''o'', ''/ 0'', ''b'', ''a'', ''r'', ''/ 0 ''...]), y necesito dividir esto en un std::vector<std::string> o similar.

Podría escribir un bucle de 10 líneas para hacer esto usando std::find o strlen (de hecho, acabo de hacerlo), pero me pregunto si hay una forma más simple / elegante de hacerlo, por ejemplo, algún algoritmo STL. Lo he pasado por alto, lo que puede ser persuadido para hacer esto.

Es una tarea bastante simple, y no me sorprendería si hubiera algún truco STL inteligente que se pueda aplicar para hacerlo aún más simple.

¿Ningún arrendatario?


Aquí está la solución que se me ocurrió, asumiendo que el búfer termina inmediatamente después de la última cadena:

std::vector<std::string> split(const std::vector<char>& buf) { auto cur = buf.begin(); while (cur != buf.end()) { auto next = std::find(cur, buf.end(), ''/0''); drives.push_back(std::string(cur, next)); cur = next + 1; } return drives; }


En C, string.h tiene este chico:

char * strtok ( char * str, const char * delimiters );

el ejemplo en cplusplus.com:

/* strtok example */ #include <stdio.h> #include <string.h> int main () { char str[] ="- This, a sample string."; char * pch; printf ("Splitting string /"%s/" into tokens:/n",str); pch = strtok (str," ,.-"); while (pch != NULL) { printf ("%s/n",pch); pch = strtok (NULL, " ,.-"); } return 0; }

No es C ++, pero funcionará.


Lo siguiente se basa en std::string tiene un constructor implícito que toma un const char* , lo que hace que el bucle sea un sistema de dos líneas muy simple:

#include <iostream> #include <string> #include <vector> template< std::size_t N > std::vector<std::string> split_buffer(const char (&buf)[N]) { std::vector<std::string> result; for(const char* p=buf; p!=buf+sizeof(buf); p+=result.back().size()+1) result.push_back(p); return result; } int main() { std::vector<std::string> test = split_buffer("wrgl/0brgl/0frgl/0srgl/0zrgl"); for (auto it = test.begin(); it != test.end(); ++it) std::cout << ''"'' << *it << "/"/n"; return 0; }

Esta solución supone que el tamaño del búfer es conocido y el criterio para el final de la lista de cadenas. Si la lista termina en "/0/0" , la condición en el bucle debe cambiarse de p!=foo+sizeof(foo) a *p .


Mis dos centavos :

const char* p = str; std::vector<std::string> vector; do { vector.push_back(std::string(p)); p += vector.back().size() + 1; } while ( // whatever condition applies );


Solución de impulso:

#include <boost/algorithm/string.hpp> std::vector<std::string> strs; //input_array must be a Range containing the input. boost::split( strs, input_array, boost::is_any_of(boost::as_array("/0")));


Una mala respuesta, en realidad, pero dudé de su reclamo de un bucle de 10 líneas para la división manual. 4 líneas lo hacen por mí:

#include <vector> #include <iostream> int main() { using std::vector; const char foo[] = "meh/0heh/0foo/0bar/0frob"; vector<vector<char> > strings(1); for (const char *it=foo, *end=foo+sizeof(foo); it!=end; ++it) { strings.back().push_back(*it); if (*it == ''/0'') strings.push_back(vector<char>()); } std::cout << "number of strings: " << strings.size() << ''/n''; for (vector<vector<char> >::iterator it=strings.begin(), end=strings.end(); it!=end; ++it) std::cout << it->data() << ''/n''; }


Una solución más elegante y real (en comparación con mi otra respuesta) utiliza getline y se reduce a 2 líneas con solo C ++ 2003, y no se requiere una contabilidad y acondicionamiento de bucles manuales:

#include <iostream> #include <sstream> #include <string> int main() { const char foo[] = "meh/0heh/0foo/0bar/0frob"; std::istringstream ss (std::string(foo, foo + sizeof foo)); std::string str; while (getline (ss, str, ''/0'')) std::cout << str << ''/n''; }

Sin embargo, tenga en cuenta que el constructor de cadenas basado en rango ya indica un problema inherente con la división en - ''/ 0''s: debe saber el tamaño exacto, o encontrar otro char-combo para el Ultimate Terminator.