Problema al usar while

Iniciado por FranAI, 23 Abril 2020, 03:48 AM

0 Miembros y 1 Visitante están viendo este tema.

FranAI

Soy principiante en cuanto a c++ respecta, mi inconveniente es el siguiente: Al pedirle al usuario que ingrese por segunda vez un numero, si el usuario ingresa la letra "n" debe terminarse el ciclo y mostrar por pantalla la cantidad de números introducidos por el usuario, así como, la suma de los resultados calculados. Mi problema es la condicion del while. Como puedo comparar un int con un char? La variable que se almacena en el segundo ingreso es de tipo entero, no deberia cambiarla a char y comparar? Como lo hago? ¿while (num2 != letra1);?

#include <iostream>
#include <stdio.h>
using namespace std;
int num;
int num2;
int i = 0;
int i2 = 0;
int i3 = 0;
int result = 0;
int result2 = 0;
int finalresult = 0;
char letra1 = 'n';
int main()
{
    do
    {
        cout << "Ingrese un numero entero: " << endl;
        cin >> num;
        i = i + 1;
        result = num * num - num;
        cout << num <<  " * " << num << " - " <<num<<  " = " << result << endl;
        cout << "Desea ingresar otro numero? " << endl;
        cin >> num2;
        i2 = i2 + 1;
        result2 = num2 * num2 - num2;
        finalresult =  finalresult + result + result2;
    }while (num2 != letra1);
    i3 = i2 + i;
    cout << i3 << " numeros ha ingresado el usuario." << endl;
    cout << "Suma de resultados calculados: " << finalresult << endl;
    return 0;
}

engel lex

probaste tu codigo? falla cuando introduces n?


por cierto mezclas librerias del standard C y C++, las librerias del standard no llevan.h, es decir, no es <stdio.h> sino <cstdio>
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

@XSStringManolo

 Te recomendaría que lo hicieses de cero de nuevo hicieses otro tipo de programas que tengas más claros mentalmente. Calculadores, conversiones de horas a minutos...


Tienes algunas cosas a mejorar:


- Faltan saltos de línea y organización para hacer el código más legible. Opcionalmente deberías añadir comentarios de para que es cada cosa, nombres de variables más descriptivos... Si no organizas todo exhaustivamente pronto montarás un buen lío cuando hagas algún programa de más de 100 lineas de código.


- Tienes un montón de variables que sobran, puedes reusar una para varias cosas o incluir en el cout la operación cuando no vayas a reusar una variable más.


- Tienes varios errores de lógica. La comprobación del while se hace al final, por lo que cuando el usuario introduzca la n vas a intentar operar con la letra n en lugar de un número porque el programa continua ejecutándo el bloque de código del do hasta que se llega al while y se comprueba que se introduzco una letra. Lo mismo pasa con los contadores (variables i) que los aumentas a pesar de que se introduzcan 2 n. Hay una solución que a mi parecer es fea y poco recomendada pero podría comprobar con un if y un static cast si se metio la letra n y hacer un break; dentro del if para saltar fuera del cuerpo del while. Tendrías que alterar un poco la estructura del código y funcionaría. A mi personalmente no es una opción que me guste y en tu caso programaría cosas más sencillas o pasaría a otra cosa, porque esto va a ser romperte mucho la cabeza para poco provecho a nivel de aprendizaje.


- Solo necesitas un contador, no 3.


- Tienes trozos de código innecesarios y repetitivos.


- El do y el casteo por el que preguntas static_cast<int>('n'); son innecesarios en este programa.


- No tienes ningún tipo de pausa en el programa. Puede que tu IDE las integre en desarrollo pero en varios sistemas si ejecutas el binario compilado, este no tiene pausa y se cierra la consola sin poder ver el resultado. Para evitarlo añade siempre antes del return 0 de la función principal main cin.get(); Si no te funciona y no sabes el por qué, agrega también cin.ignore(); antes del cin.get(); Estos métodos vienen con el cin en la biblioteca iostream.


- Puedes usar i += 1 o usar ++i en lugar de i = i + 1; Todas las formas hacen casi lo mismo.


- No hace falta que llames 2 veces seguidas al cout, puedes saltar de línea tranquilamente.


- char letra no te hace falta, pero en caso que lo pongas deberías declaralo como const o usando un #define ya que se supone que la letra va a ser siempre la misma.







WHK

#3
Citar- El do y el casteo por el que preguntas static_cast<int>('n'); son innecesarios en este programa.

Y como te aseguras que el usuario no ha introducido otra cosa que no sea un valor numérico? y como sumas el total de todas las operaciones del loop?

CitarNo tienes ningún tipo de pausa en el programa. Puede que tu IDE las integre en desarrollo pero en varios sistemas si ejecutas el binario compilado, este no tiene pausa y se cierra la consola sin poder ver el resultado.

No veo la necesidad de hacer una pausa, vamos, es una aplicación de terminal, no vienes desde windows y le haces doble click al ejecutable, se supone que lo estás llamando desde el interprete de comandos, a demás.

Citarchar letra no te hace falta

Y como finaliza la instrucción del input del while?

Lo que te hace falta FranAI es transformar tu input a integer siempre y cuando este sea un valor numérico, en caso contrario no podrás transformar "n" a entero y te dará un error de memoria y la validación de contenido de un valor entero de un std string lo debes hacer recorriendo cada caracter, yo transformé cada uno al valor decimal y comrpobé si era el valor de un dígito. También entendí que la suma de los loops es para sumar el resultado de cada operación dentro del loop, asi que lo modifiqué poniendo las variables dentro del mismo loop para evitar globalizar las variables y tener basura en la memoria cuando liberes el proceso, las variables temporales las puse dentro del mismo while para que se autodestruyan en cada iteración. A demás, las palabras no se consideran como operaciones matemáticas asi que el contador lo puse justo después de la validación. Mira, algo así:

#include <iostream>
#include <string>

int main()
{
   std::string input;
   int totals  = 0;
   int nInputs = 0;

   while(1)
   {
       std::cout << "Ingrese un numero entero (o 'n' para finalizar): "; // no flush
       std::cin >> input;
       
       if(input.compare("n") == 0)
       {
           break;
       }

       bool isNumeric = true;
       for(int i = 0; i <= (input.length() - 1); i++)
       {
           if(((int)input[i] < 48) || ((int)input[i] > 57)) // decimal
           {
               isNumeric = false;
               std::cout << "El valor no es numérico. Intentalo nuevamente." << std::endl;
               break;
           }
       }

       if(!isNumeric)
       {
           continue;
       }

       nInputs++;

       int num   = std::stoi(input);
       int total = num * num - num;
       totals += total;

       std::cout << num <<  " * " << num << " - " << num <<  " = " << total << std::endl;
   }

   std::cout << nInputs << " numeros ha ingresado el usuario." << std::endl;
   std::cout << "Suma de resultados calculados: " << totals << std::endl;

   return 0;
}


Para compilar y ejecutar:

whk@machine:~/Escritorio$ g++ test.cpp -o test
whk@machine:~/Escritorio$ file test
test: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, not stripped
whk@machine:~/Escritorio$ ./test
Ingrese un numero entero (o 'n' para finalizar): 1
1 * 1 - 1 = 0
Ingrese un numero entero (o 'n' para finalizar): 5
5 * 5 - 5 = 20
Ingrese un numero entero (o 'n' para finalizar): abc
El valor no es numérico. Intentalo nuevamente.
Ingrese un numero entero (o 'n' para finalizar): 500
500 * 500 - 500 = 249500
Ingrese un numero entero (o 'n' para finalizar): n
4 numeros ha ingresado el usuario.
Suma de resultados calculados: 249520


También podrías simplificar "n*n-n" como "n*(n-1)", factorización de números semiprimos ;)

Espero te sirva. Saludos.

@XSStringManolo

#4
 No entiendo para que tanto código para algo tan sencillo.
Ni las críticas del comentario sobre el do, que tu tampoco usas. Ni del static_cast que tampoco usas...


Código (cpp) [Seleccionar]
#include <iostream>


using namespace std;


int main() {
int n = 1, i = 0, r = 0;


while(n) {
   cout << "Ingrese un número entero o 0 para salir." << endl;
   cin >> n;


   if(n) {
     ++i;
     cout << n << " * " << n << " - " << n << " = " << n*n-n << endl;
     r += n*n-n;
   }
}


cout << i << " numeros Ingresados." << endl <<
"Suma de resultados calculados: " << r << endl;

cin.get();
return 0;
}




WHK

Porque 0 para factorización si es un número válido, solo te quisiste ahorrar la validación numérica.

saludos.

@XSStringManolo

Cita de: WHK en 23 Abril 2020, 21:45 PM
Porque 0 para factorización si es un número válido, solo te quisiste ahorrar la validación numérica.

saludos.
Eso del 0 no lo sabía. Se puede meter un menú entonces antes de introducir el número. 1. Introducir número 2. Salir. O si quieres con letras. if(opcion == 'y') {} else if(opcion == 'n') {} else {cin >> opcion}


Más que nada es para no complicarle el código a alguien que empieza.

WHK

Citarif(opcion == 'y') {}

No puedes hacer una comparación de un char de 1 dimension con un std::string, y cómo sabrías si el valor contiene otra letra y deba ser procesado para multiplicar o no?.

@XSStringManolo

#8
Cita de: WHK en 23 Abril 2020, 22:13 PM
No puedes hacer una comparación de un char de 1 dimension con un std::string, y cómo sabrías si el valor contiene otra letra y deba ser procesado para multiplicar o no?.
Es que no comparo con string. opcion es un char y 'y' también es un char literal.
Omito la comprobación porque considero que es innecesario para un programa sencillo para un usuario nuevo. En caso de necesitar forzosamente la comprobación usaría la función isDigit() de la librería ctype

http://www.cplusplus.com/reference/cctype/isdigit/

dijsktra

Mas sencillo.

#include <stdio.h>
#include <stdlib.h>


int main(int argc, char *args)
{
  int n,acum,many;
  many=acum=0;
  while (scanf("%d",&n)==1)
    {
      acum +=n;
      many++;
    }
  if (ferror(stdin))
    {
      perror("scanf");
      exit(1);
    }
  printf("\n%d %d\n",many,acum);
  return 0;
}


Pruebas
gcc stream.c -o main && ./main
10 20 30 40 50 n

5 150
Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)