c++ string

c++ - Cómo crear una nueva cadena sin espacios desde otra cadena usando un bucle



string (3)

Sugiero no usar un lazo hecho a mano. Puede usar std::copy_if en combinación con una expresión lambda para formular su condición. Esto será más estable que su implementación (¿qué sucede si la longitud de su cadena s excede la capacidad de un int ?). Creo que también mejora la legibilidad.

#include <algorithm> #include <iostream> #include <string> int main() { std::string s = "here is some text"; std::string t = ""; auto comp = [&](const char c) { return std::isalpha(c); }; std::copy_if(s.begin(), s.end(), std::back_inserter(t), comp); std::cout << t << std::endl; }

Comencé tratando de escribir una función que eliminaría espacios de una cadena, pero ahora que he visto una serie de soluciones de otras personas para ese problema, estoy tratando de entender exactamente qué salió mal en mi código / por qué std::cout << t << std::endl; al final no da salida a nada.

Cuando std::cout << t[count]; durante el ciclo (la declaración que se comenta a continuación) saldría correctamente a la consola: hereissometext sin espacios. Cuando tengo std::cout << t[0] << std::endl; al final, genera correctamente h , t[1] como e , t[2] como r , y así sucesivamente. Sin embargo, cuando intento generar t al final, genera un espacio en blanco y t.size() genera 0 .

Soy bastante nuevo en la codificación, así que perdóname si esta es una pregunta completamente obvia.

std::string s = "here is some text"; std::string t = ""; int count = 0; for (int i = 0; i < s.size(); i++) { if (std::isalpha(s[i])) { t[count]+=s[i]; // std::cout << t[count]; count++; } } std::cout << t << std::endl;


Tiene un comportamiento indefinido en su bucle, ya que inserta en una std::string usando su operator[] sin asegurarse de que tenga el tamaño correcto. En su lugar, puede usar

t.push_back(s[i]);

que no solo inserta un char , sino que también se asegura de que el búfer interno se (re) asigne cuando es demasiado pequeño para la nueva cadena.

Tenga en cuenta además que realmente no necesita la variable de count . std::string siempre realiza un seguimiento de su longitud, por lo que t.size() siempre generará el valor de su count actual (una vez que arregle el UB, por supuesto).

Por otro lado, copiar las partes de una secuencia que coinciden con un determinado criterio es una tarea común, y existe una plantilla de biblioteca específica que hace exactamente esto y lo libera de un bucle hecho a mano:

#include <algorithm> std::copy_if(s.cbegin(), s.cend(), std::back_inserter(t), [](char c){ return std::isalpha(c); });

Finalmente, también tenga en cuenta el comentario de @MatthieurFoltzer sobre el comportamiento de std::isalpha , que podría valer la pena tener en cuenta.


t[count]+=s[i];

Esto no funciona así. Con esto puede cambiar los caracteres existentes de la cadena. Pero como su cadena está vacía, eso causa un comportamiento indefinido. Para agregar a la cadena, cambie esa línea a esto en su lugar:

t += s[i];

E imprimirá la salida deseada de hereissometext . Puede encontrar la documentación del operador += para cadenas here .