Soy bastante nuevo en C ++ y lo estoy aprendiendo por mi cuenta, así que, por favor, sea algo suave conmigo. Lo que estoy tratando de hacer: imprimir una matriz que tenga nombres de programa y pedirle al usuario que escriba el nombre de un ...

0
Markus Vaittinen 15 mar. 2021 a las 02:14

1 respuesta

La mejor respuesta

Avance un par de décadas en C ++ y busque el contenedor STL std :: map que mantiene un conjunto único de pares clave / valor. En su caso, desea asociar (mapa) una cadena con un puntero de función de modo que cuando el usuario ingrese "keyControl", se llame a la función keyControl(), y así sucesivamente.

En su caso, puede completar un std::map con sus pares clave / valor creando un mapa que asocie un puntero std::string y void(*)(void) como un par, p. Ej.

    /* std::map with string as key and function pointer as value */
    std::map<std::string, void(*)(void)> proglist {{"keyControl", keyControl},
                                                   {"randomNumber", randomNumber}};

Entonces es simplemente una cuestión de hacer un bucle continuo, pedirle al usuario que ingrese y verificar si la entrada coincide con una de las claves en std::map, si lo hace, usted ejecutó la función mapeada.

getline() se usa para ingresar en un std::string (lea nuevamente la página sobre por qué gets() NUNCA debe usarse). C ++ proporciona una sobrecarga de == para comparar la igualdad de cadenas. Puede establecer varias condiciones de salida según el estado de la secuencia después de su llamada a getline() o según el contenido de la entrada completa. Por ejemplo:

    std::string line {};    /* line for input */
    
    while (1) { /* loop continually */
        std::cout << "\nenter program name: ";  /* prompt for input */
        /* read line, break on manual EOF, empty input or "quit" */
        if (!getline (std::cin, line) || line.length() == 0 || line == "quit")
            break;

Si el usuario genera un manual EOF ( Ctrl + d Linux o Ctrl + z Windows), si la cadena está vacía (por ejemplo, el usuario simplemente presionó Ingrese ) o la cadena leída es "quit" - ajuste para satisfacer sus necesidades.

Todo lo que necesita hacer para verificar si la entrada coincide con una clave en su std::map es usar la función miembro .find() que devolverá un puntero al par mapeado si se encuentra o devolverá el final de { {X2}} si no se encuentra. Se accede a la parte del valor del par clave / valor que se encuentra en el mapa a través del nombre de miembro second (la clave es first, el valor es second). Así que puede hacer:

        /* read line, break on manual EOF, empty input or "quit" */
        if (!getline (std::cin, line) || line.length() == 0 || line == "quit")
            break;
        auto found = proglist.find (line);  /* search for input in map */
        if (found == proglist.end()) {      /* if not found, show error */
            std::cerr << "  error: no matching program name.\n";
            continue;
        }
        found->second();        /* otherwise execute the function */

En resumen, tendrías:

#include <iostream>
#include <string>
#include <map>

void keyControl()
{
    std::cout << "keyControl() called.\n";
}

void randomNumber()
{
    std::cout << "randumNumber() called.\n";
}

int main() {
    
    /* std::map with string as key and function pointer as value */
    std::map<std::string, void(*)(void)> proglist {{"keyControl", keyControl},
                                                   {"randomNumber", randomNumber}};
    std::string line {};    /* line for input */
    
    while (1) { /* loop continually */
        std::cout << "\nenter program name: ";  /* prompt for input */
        /* read line, break on manual EOF, empty input or "quit" */
        if (!getline (std::cin, line) || line.length() == 0 || line == "quit")
            break;
        auto found = proglist.find (line);  /* search for input in map */
        if (found == proglist.end()) {      /* if not found, show error */
            std::cerr << "  error: no matching program name.\n";
            continue;
        }
        found->second();        /* otherwise execute the function */
    }
}

Ejemplo de uso / salida

$ ./bin/map_str_fn

enter program name: foo
  error: no matching program name.

enter program name: keyControl
keyControl() called.

enter program name: randomNumber
randumNumber() called.

enter program name: quit

Familiarizarse con los contenedores STL le ahorrará un sinfín de problemas con C ++. La biblioteca tiene más de una década y media de ajustes de validación y eficiencia y será mucho más robusta que cualquier cosa que "prepares" sobre la marcha.

Revisa las cosas y avísame si tienes preguntas.

0
David C. Rankin 15 mar. 2021 a las 00:18