La división de cadena en un vector<cadena> de las palabras

De Acelerado C++(libro), me encontré con este código, que es idéntico programa, pero el procesado en el programa en sí es diferente, y que me confunde en alguna parte.

El código de abajo, bueno, es obvio que va a la salida de cada palabra una por una(bucles), basado en la entrada del usuario después de que el usuario final que incluye-de-archivo, a continuación, cierre el programa.

int main()
{
    string s;
    while (cin >> s)
        cout << s << endl;
    return  0;
}

A diferencia del código anterior, esto va a guardar cada palabra en un vector, a continuación, utilizar el índice de i y j para detectar la no-carácter de espacio en blanco, y la verdadera pregunta es, yo no entiendo cómo es que sucede con el vector.

Lo que es el espacio en blanco en vector? Un elemento?

Al principio, pensé que el programa pasara a través de cada carácter, porque pensé que el el espacio en blanco es de carácter(que i y j funcionalidad es), entonces, el libro venir y dijo que proceder a través de cada palabra, no sé cómo poner a prueba a mí mismo, como puedo ver cómo el proceso interno en el propio compilador..

vector<string> split(const string& s)
{
    vector<string> ret;
    typedef string::size_type string_size;
    string_size i = 0;

    //invariant: we have processed characters [original value of i, i) 
    while (i != s.size())
    {
        //ignore leading blanks
        //invariant: characters in range [original i, current i) are all spaces
     while (i != s.size() && isspace(s[i]))
         ++i;

     //find end of next word
     string_size j = i;
     //invariant: none of the characters in range [original j, current j)is a space
     while (j != s.size() && !isspace(s[j]))
         j++;
         //if we found some nonwhitespace characters 
         if (i != j) {
             //copy from s starting at i and taking j - i chars
             ret.push_back(s.substr(i, j - i));
             i = j;
         }
    }
    return ret;
}

int main() {
    string s;
    //read and split each line of input 
    while (getline(cin, s)) {
        vector<string> v = split(s);

        //write each word in v
        for (vector<string>::size_type i = 0; i != v.size(); ++i)
             cout << v[i] << endl;
    }
    return 0;
}
  • Que faltan algunos llaves ({, }) en el código.
  • bueno, acabo de copiar del libro
InformationsquelleAutor Vastor | 2011-12-08

2 Kommentare

  1. 3

    El código que has publicado anteriormente hace no dividir una línea de texto en palabras, basadas en el espacio en blanco, se divide una línea en los personajes. Sin embargo, si el código era en realidad compilable y no falta ningún llaves necesarias ({, }). EDICIÓN: en Realidad si se divide palabras o caracteres individuales depende de donde las llaves vaya, línea de fondo es que el código no compila.

    Aquí es una versión del código que se divide cada palabra, en lugar de que cada carácter, simplemente moviendo el último if declaración en split fuera de lo inmediato while bloque:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    vector<string> split(const string& s)
    {
       vector<string> ret;
       typedef string::size_type string_size;
       string_size i = 0;
    
       //invariant: we have processed characters [original value of i, i) 
       while (i != s.size()) {
          //ignore leading blanks
          //invariant: characters in range [original i, current i) are all spaces
          while (i != s.size() && isspace(s[i]))
             ++i;
    
          //find end of next word
          string_size j = i;
          //invariant: none of the characters in range [original j, current j)is a space
          while (j != s.size() && !isspace(s[j]))
             j++;
    
          //if we found some nonwhitespace characters 
          if (i != j) {
             //copy from s starting at i and taking j - i chars
             ret.push_back(s.substr(i, j - i));
             i = j;
          }
       }
       return ret;
    }
    
    int main() {
       string s;
       //read and split each line of input 
       while (getline(cin, s)) {
          vector<string> v = split(s);
    
          //write each word in v
          for (vector<string>::size_type i = 0; i != v.size(); ++i)
          cout << v[i] << endl;
       }
       return 0;
    }

    Lo que sucede a la string pasa a split es:

    • Mientras todavía los caracteres de la cadena (while (i != s.size()))
      • Mientras estamos leyendo un espacio de la cadena de while (i != s.size() && isspace(s[i]))
        • Incrementar el contador hasta llegar al inicio de una palabra (++i)
      • Definir el final de la palabra como el inicio de la palabra (string_size j = i)
      • Mientras estamos todavía en el interior de esta palabra y no a un espacio (while (j != s.size() && !isspace(s[j])))
        • Incrementar el contador que indica el final de la palabra (j++)
      • Si hay algunos de los caracteres de espacio en blanco – final es mayor que la de inicio (if (i != j))
        • Crear una sub-cadena desde el punto inicial hasta el punto final de la palabra (s.substr(i, j - i)), y añadir la palabra a la vector (ret.push_back(..)).
      • Enjuague y repita.
    • no eres el único que editar el título?, bien, he dicho en el título de «Idéntico programa», lo que quiero decir, Si u ver en el primer código, tiene la misma salida de resultado como el segundo código, becoz de que, el código del libro NO es la falta de cualquier llaves, sólo el espacio de en el código es cojo/no organizados, de todos modos, a partir de su respuesta, yo aún no obtener la respuesta real(todavía en vagos), bcoz, Estoy tratando de preguntar sobre «cómo el compilador procesa la entrada basado en el código», siendo la explicación a continuación el código ayudar a darme alguna pista…
    • El primer ejemplo de código y el fijo que he publicado tienen la misma salida. Y hay soportes de falta en el segundo ejemplo de código, o bien contar con ellas o intentar compilarlo y verás.
    • así que si estoy en lo correcto, el compilador procesa cada «personaje», y luego se almacena en el elemento(vector) y, a continuación, acceder al elemento de salida en la pantalla. parece ser mi culpa por alto la posición de push_back(que puso char/palabra en el elemento), pensé que el compilador de la comprobación de la palabra y el carácter en el elemento en sí…
    • por cierto, la falta de soporte en el post es mi culpa(errata),n fijo, tal vez usted puede copiar y pegar de nuevo a un compilador para comprobar cómo el segundo código funciona 🙂
    • Sí, el código es ahora. También puede descargar los ejemplos de código de Acelerado C++ libro en su página web: acceleratedcpp.com. Cada personaje se procesa uno por uno con el fin de encontrar una palabra entre dos espacios. Cada palabra se inserta en la final de la vector.
  2. 1

    Si se acaba la división basada en el espacio, entonces usted no necesita escribir un método personalizado. STL tiene opciones para usted.

            std::string line;
            std::vector<std::string> strings;
            while ( std::getline(std::cin, line))
            {
                 std::istringstream s ( line);
                 strings.insert(strings.end(), 
                     std::istream_iterator<std::string>(s),  
                     std::istream_iterator<std::string>());
            }
    
         // For simplicity sake using lambda.   
            std::for_each(strings.begin(), strings.end(), [](const std::string& str)
            {
                std::cout << str << "\n";
            });
    • O std::copy(std::istream_iterator<std::string>(s), std::istream_iterator<std::string>(), std::back_inserter(strings)) y de manera similar a mostrar std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(std::cout, std::endl))
    • No estoy pidiendo un código(que funciona de la misma como la mía) para compilar, me estoy preguntando acerca de cómo un compilador procesa el programa, que espero que algunos pueden explicar como AusCBloke hizo.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea