0

Estoy empezando a programar en C++ y tengo este ejercicio:

Realizar una función que reciba como parámetros:

  1. por referencia constante un vector de enteros
  2. un entero sin signo (n)
  3. un entero sin signo (m)

y devuelva un vector de bool que corresponderá al valor del bit m-simo (en la posición m de la representación binaria del entero) de los elementos en posición múltiplo de n del vector de enteros.

En el programa principal se leerán los datos de un fichero cuyo nombre se pasará como primer parámetro al programa. El segundo parámetro será el valor del bit a considerar (m). El tercer parámetro será le parámetro n de la función, si no está disponible valdrá 2.

El nombre del fichero deberá comenzar por “datos” y terminar por “.dat” si falta alguno se añadirá antes de acceder al fichero.

Mi código:

//Librerías
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

//PARÁMETROS DE ENTRADA Y FUNCIONAMIENTO DEL CÓDIGO
std::vector<bool> Msimo (const std::vector<int>&datos, unsigned int n, unsigned
int m){
  
  //vector de múltiplos de n
  std::vector<int> Vectmult;
  
  
  //creamos vector de strings binario
  std::string binario;
  std::vector<std::string> VectBinario;
  
  //creamos el vector de salida
  std::vector<bool> VectMsimo;
  
  //recorremos el vector de enteros de entrada
  for(unsigned i = 0; i < datos.size(); i++){
    //ver qué enteros del vector son múltiplos de n
    if (datos[i] % n == 0){
      Vectmult.push_back(datos[i]);
    }
  }
  
  //pasamos a binario los enteros múltiplos de n
  for (unsigned i = 0; i < Vectmult.size(); i++){
    while (Vectmult[i] != 0){
        binario += ( Vectmult[i] % 2 == 0 ? "0" : "1" );
        Vectmult[i] /= 2;
    }
    //guardamos en un vector nuevo los enteros pasados a binario
    VectBinario.push_back(binario);
  }
  
  //buscamos la posición m en cada número del vector
  for (unsigned i = 0; i < VectBinario.size(); i++){
    for (unsigned j = 0; j < VectBinario[i].size(); j++){
      if (j == m){
        //guardamos en un nuevo vector los valores de la posición m
        VectMsimo.push_back(VectBinario[i][j]);
      }
    }
  }
  
  return VectMsimo;
}

int main(int argc, char* argv[]){
  
//Lectura de parámetros de entrada
  //nombre del fichero
  if (argc < 2){
    std::cerr << "Error 1: es necesario un fichero" << std::endl;
    return 1;
  }
  
  //leemos el nombre del fichero
  char* nombre = argv[1];
  std::string nombrefichero = nombre;
  
  //añadimos "datos" al principio del nombre del fichero en caso de que no
  //lo tenga
  std::size_t encontrar = nombrefichero.find("datos");
  if (encontrar == std::string::npos){
    nombrefichero == "datos" + nombrefichero;
  }
  
  //añadimos ".dat" al final del nombre del fichero en caso de que no lo
  //tenga
  std::size_t encontrar1 = nombrefichero.find(".dat");
  if (encontrar1 == std::string::npos){
    nombrefichero =+ ".dat";
  }  
  
//Lectura del documento
  std::fstream fent(nombrefichero);
  
  //fallo de lectura del documento
  if (fent.fail()){
    std::cerr << "Error 2: fallo de lectura del documento" << std::endl;
    return 2;
  }
  
  //lectura de los valores del fichero
  int valor;
  std::vector<int> valores;
  
  fent >> valor;
  while (fent.good()){
    valores.push_back(valor);
    fent >> valor;
  }
  
  //lectura de los parámetros m y n
  unsigned int m = 0;
  if (argc >= 3) {
    try {
      m = std::stoi(argv[2]);
    }
    catch (unsigned int m) {
      std::cerr << "Error 3: fallo de lectura del parámetro m" << std::endl;
          return 3;
    }
  }  

  unsigned int n = 2;
  if (argc >= 3) {
    try {
      n = std::stoi(argv[2]);
    }
    catch (unsigned int n) {
      std::cerr << "Error 4: fallo de lectura del parámetro n" << std::endl;
          return 4;
    }
  }
  
  //Creamos el vector donde se guardarán los resultados
  std::vector<bool> VectorMsimo;
  VectorMsimo = Msimo (valores, m, n);
  
  std::cout << "Resultado: " << std::endl;
  for (unsigned i = 0; i < VectorMsimo.size(); i++){
    std::cout << VectorMsimo[i] << std::endl;
  }
  
  return 0;
}

Patricia
  • 3
  • 2
  • 1
    ¿Responde esto a tu pregunta? [Excepción de coma flotante (\`core' generado) trabajando con std::vector](https://es.stackoverflow.com/questions/123440/excepci%c3%b3n-de-coma-flotante-core-generado-trabajando-con-stdvector) – Juan Rivera Jan 13 '21 at 13:24
  • El error no aparece al compilar sino al ejecutar, no es lo mismo y es un detalle importante, ya que entonces el error no es del compilador sino de tu propio programa – eferion Jan 13 '21 at 13:31
  • Por otro lado tienes dos errores. El que se relaciona con la pregunta duplicada se encuentra en el último bucle de tu programa... fíjate que justo ahí tienes el temido `<=`. El segundo error es en el bucle anidado (líneas 40 y 41). `j` no debería iterar de 0 a `VectBinario.size()` sino de 0 a `VectBinario[i].size()` ya que vas a usar `j` para recorrer el contenido de `VectBinario[i]` – eferion Jan 13 '21 at 13:33
  • Pero vamos, ambos errores son básicamente lo mismo, excedes los límites del vector. Para tu conocimiento, el método `at` lanza una excepción si se exceden los límites del array. Si usas `at` te sugiero usar `try-catch`. Si, por el contrario, sabes que los índices son válidos (para eso usas bucles que iteran de 0 a `size`), puedes usar los corchetes, que no hacen chequeos – eferion Jan 13 '21 at 13:35
  • ¡Muchas gracias por tu comentario @eferion! He implementado los cambios que me indicas pero sigue apareciendo el mismo mensaje al ejecutarlo. – Patricia Jan 13 '21 at 15:08

1 Answers1

0

Por favor, para futuras preguntas, no apliques las soluciones a la pregunta porque entonces la misma se desvirtúa. Es preferible crear una pregunta nueva.

Dicho esto, vamos con tu problema. Se resume en dos líneas:

  • Por un lado tenemos la función

      std::vector<bool> Msimo (const std::vector<int>&datos, unsigned int n, unsigned int m)
    
  • Y por otro tenemos la llamada a la función

      VectorMsimo = Msimo (valores, m, n);
    

Fíjate ahora que la función espera recibir primero n y después m, mientras que tu le estás pasando primero m y después n.

Esto por sí solo ya indica un problema, que no sería del todo catastrófico si no le estuvieses asignando a m el valor 0:

unsigned int m = 0;

este 0 pasa a la función como n. Entonces se ejecuta la siguiente línea y se va todo al garete:

if (datos[i] % n == 0){

Todos aquí deberíamos saber que x/0 es una indeterminación y, como tal, es una operación que el compilador no puede resolver por si mismo.

eferion
  • 49,291
  • 5
  • 30
  • 72
  • Disculpa, es la primera vez que utilizo esta página y no sabía cómo se utilizaba. ¡Muchísimas gracias! Me ha resuelto el problema. – Patricia Jan 13 '21 at 15:29
  • No te preocupes, no te estaba regañando. Era a título informativo – eferion Jan 13 '21 at 15:30