Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - K-YreX

#701
Vale, a ver, los errores son varios y te los voy dejando por aquí:
  • Antes de nada no está incluido <iostream> para poder hacer las entradas/salidas de pantalla <cin> y <cout>.
  • Si inicializas <distMasCorta = 0> y luego buscas dos puntos cuya distancia sea menor a eso, no creo que los encuentres nunca... :silbar:
  • Los dos bucles <for> anidados están al revés. El exterior es el que tiene que acabar antes y el interior el que tiene que llegar hasta el final.

    Y ahora unos consejos que nunca están de más :-X:
  • No utilices <conio.h>. No es estándar por lo que algunos compiladores no lo admiten.
  • El <getch()> que usas de <conio.h> sustitúyelo por <cin.get()> que está en <iostream>.
  • Las librerías que acaban en ".h" (versión C) tienen su versión de C++ sin el ".h" y empezando por "c" <cmath>.
  • El bucle <for> interno en vez de inicializar <m = i> y después usar siempre <m+1>; inicialízalo en <m = i+1> y así sólo tendrás que usar <m> luego.
#702
Esto es porque estás declarando el prototipo de la función <f_obtenerEdad()> dentro del <namespace Agenda> pero la implementación de la función lo estás haciendo fuera; lo que sea hace confuso.

Para que funcione correctamente debes hacer que tanto el prototipo como la implementación pertenezcan al <namespace Agenda>.
Código (cpp) [Seleccionar]

namespace Agenda{
    class Persona{
        int edad;
        public:
            friend int f_obtenerEdad(const Persona&);
    };

    int f_obtenerEdad(const Persona &p){
        return p.edad;
    }
}


Al hacerlo en ficheros separados debes especificar que la implementación también pertenece al <namespace Agenda> por eso que tienes que ponerlo para que funcione.
Puedes leer un poco más al respecto AQUÍ :-X
#703
Si puedes especificar un poco más cuando dices que los resultados difieren o que no lo hace de forma completa... En principio estoy dando por supuesto que ambos compilan sin problemas. :-X
#704
Ahora ya funciona pero si te has dado cuenta, pides los datos dos veces seguidas. Una vez en el <main> y otra vez en la función <matrizCuadrada()>...
Te comento las diferencias entre el filtro <do while> y el <while> ya que esto se puede hacer de ambas formas.

Un bloque de código dentro de un <do while> siempre se ejecuta al menos una vez aunque la condición sea falsa ya que primero está el <do> y luego el <while>. Es como "primero haces y luego compruebas". En cambio un <while> es justo lo contrario; "primero compruebas y luego ya si eso, haces".

Aquí te muestro un bloque infinito. ¿Por qué si la condición de primeras no se cumple? Pues porque primero mostramos el 0, luego lo incrementamos <iteracion = 1> y luego comprobamos si es mayor que 0. Y como sí que lo es pues ya se ejecuta de forma infinita.
Código (cpp) [Seleccionar]

int iteracion = 0;
do{
    cout << iteracion << endl;
    iteracion++;
}   while(iteracion > 0);


Lo mismo con un <while>. La parte interna del bucle nunca se ejecuta. Al principio iteracion vale 0, comprobamos si es mayor que 0 y como no lo es, se acabó.
Código (cpp) [Seleccionar]

int iteracion = 0;
while(iteracion > 0){
    cout << iteracion << endl;
    iteracion++;
}


Entonces ahora te muestro las opciones que tienes:
  • Alternativa 1: Pedir los datos únicamente dentro de <matrizCuadrada()>. Entonces sería con un <do while>.
    Código (cpp) [Seleccionar]

    void matrizCuadrada(int m[][TAM], int &nFil, int &nCol){
        do{
            pedirDatos(nFil, nCol);
        }   while(nFil != nCol);
        // el resto de la funcion
    }


  • Alternativa 2: Pedir los datos en el <main> y dentro de la función <matrizCuadrada()> comprobarlos para que si no son iguales los pida de nuevo.
    Código (cpp) [Seleccionar]

    void matrizCuadrada(int m[][TAM], int &nFil, int &nCol){
        while(nFil != nCol)
            pedirDatos(nFil, nCol);
        // el resto de la funcion
    }


  • Alternativa 3: La más correcta creo yo. Para no tener que ir pasando siempre las dimensiones por referencia, que podrías acabar modificándolas sin querer; haz el filtro dentro de <pedirDatos()> y así te aseguras que cuando acaba esa función la matriz ya es cuadrada.
    Código (cpp) [Seleccionar]

    void pedirDatos(int &nFil, int &nCol){
        do{
            cout << "Introduce las dimensiones de la matriz (NxN): ";
            cin >> nFil >> nCol;
        }   while(nFil != nCol);
    }

    Con esta última opción ya no tienes que usar siempre el paso por referencia y así evitar errores mayores.

    Es más, yo dejaría el esquema general del programa en algo así :-X:
    Código (cpp) [Seleccionar]

    void pedirDatos(int&, int&);
    void generarMatriz(int [][TAM], const int, const int);
    void mostrarMatriz(const int [][TAM], const int, const int);
    bool esSimetrica(const int [][TAM], const int, const int);

    En el caso de <esSimetrica()>. Cuando se usa una función para comprobar algo es mejor que devuelva <true/false> y luego tú ya verás lo que haces con ello. Imagina un programa muy grande donde tienes que comprobar si 100 matrices son simétricas y vas mostrando por pantalla el resultado de cada una, cuando no es necesario.
    Entonces es mejor hacer que devuelva un <bool> de si es simétrica o no y ya en el <main> haces lo que quieras. Algo así:
    Código (cpp) [Seleccionar]

    bool esSimetrica(const int matriz[][TAM], const int nFil, const int nCol){
        bool simetrica = true;
        for(size_t i = 0; i < nFil && simetrica; i++)
            for(size_t j = 0; j < nCol && simetrica; j++)
                simetrica = matriz[i][j] == matriz[j][i];
        return simetrica;
    }

    int main(){
        // todo el programa
        if(esSimetrica(matriz, nFil, nCol))
            cout << "La matriz es simetrica" << endl;
        else
            cout << "La matriz no es simetrica" << endl;
    }
#705
Al primer ejemplo no le veo mucha complicación, un <for> se ejecuta mientras la condición (segundo campo del <for>) sea verdadera (1). Los campos de inicialización (primer campo) y actualización (tercer campo) pueden quedarse vacíos como es el caso aunque siempre se ha comentado que no es una buena práctica ya que en otros lenguajes no está permitido este uso.
Se ejecuta el <for> y como la condición es falsa (0) termina y sale.

En cambio, en el segundo ejemplo es todo lo contrario, el <for> no termina nunca ya que la condición es siempre verdadera (1) y como ya ha comentado EdePC, como el <for> acaba en punto y coma (;) la instrucción del <assert(1)> no se ejecutará nunca ya que no pertenece al cuerpo del <for> y este genera un bucle infinito.
#706
Te recomiendo que no uses variables globales ya que no es muy recomendado para casos como este... Además de que estás usando la mayoría de funciones con parámetros (excepto <pedirDatos()>) así que con cambiar esa por:
Código (cpp) [Seleccionar]

void pedirDatos(int &nFil, int &nCol);


Además hay un problema en <matrizCuadrada()>. Imagina que introduces <nFil> != <nCol>... Te dirá que la matriz debe ser cuadrada y te volverá a pedir los datos pero no la construirá. La forma más común de resolver esto es usar un filtro. Te dejo un ejemplo para que tú lo adaptes a tu código.
Código (cpp) [Seleccionar]

do{
    cout << "Introduce un numero positivo: ";
    cin >> positivo;
}   while(positivo < 0);
// una vez salgas del bucle el numero sera positivo


Ahora imagina el otro caso, a la primera introduces unas dimensiones iguales (<nFil> == <nCol>)... Primero se llamará a la función <rellenarMatriz()> que está en el <else> de la función <matrizCuadrada()> y después a la función <rellenarMatriz()> que está en el <main>. Por eso te pide los valores dos veces.

Unas recomendaciones de diseño, no de funcionalidad:
  • Sustituye el <system("pause")> por <cin.get()>. Va a hacer lo mismo y evitas una llamada al sistema.
  • Las librerías que acaban en ".h" (stdlib.h) tienen su propia versión de C++ sin el ".h" y empezando por "c" (cstdlib).
  • Y como he dicho al principio, evitar el uso de variables globales.

    Si ya de paso cambias las etiquetas de código por las de C++ mejor. Ya que las <i> entre corchetes [] no aparecen ya que se confunden con la etiqueta de letra cursiva y el código se hace más complicado de interpretar... :-X
#707
Programación C/C++ / Re: ayuda con este tema
28 Febrero 2019, 12:21 PM
Cita de: sofia555555 en 28 Febrero 2019, 05:32 AM
Buenas noches a todos , tengo una duda chicos estoy haciendo un programa sobre un  ascensor y entonces
por ejemplo esta en planta Baja (PB)

son 12 pisos y quiero que nada mas tenga 4 paradas que serian PB-4-8-12

y yo elijo el numero 4

entonces quiero mostrar en pantalla lo siguiente

Piso = PB  es como inicia el programa pero quiero cuando arranque el ascensor  muestre en pantalla la siguiente secuencia

Piso= PB
Piso= 1
Piso= 2
Piso= 3
Piso= 4

Y ahi se detenga

entonces yo coloco lo siguiente

Código (cpp) [Seleccionar]


if(piso<0){
Piso=Piso+1;
Sleep(3000); // pongo 3 segundos por cada piso que sube es lo que tarda
}



Mis dudas son como haria que se detenga en 4  y como haria que la variable Piso pueda cambiar de PB a numero  , hay alguna variable que pueda utlizar caracteres y enteros?

Si quieres que se detenga en el 4 pues con un condicional, sencillo.
Para el tema de mezclar letras (PB) con números (1, 2, 3...) tienes varias opciones:
  • Usar <string> o <char> y entonces representar los números como caracteres en vez de como números. Si luego quieres incrementar algún valor tendrás que usar una función que los transforme de <char> a <int> y después a <char> nuevamente.
  • Usar <int> y que PB sea el 0. Luego cuando se vaya a mostrar la planta, hacer un condicional para que si la planta es el 0, se muestre "PB" y sino que se muestre el número de la planta.
  • Igual también te sirve usar una enumeración <enum>.
#708
Como te ha comentado CalgaryCorpus el error está en el signo <= que debería ser sólo < ya que sino lo que ocurre es que el propio número como es divisible consigo mismo se suma su valor a la suma y entonces nunca coincide.

Solucionado el problema te dejo un ćodigo correspondiente a tu misma función pero un poco más estética:
Código (cpp) [Seleccionar]

bool isPerfect(size_t number){
size_t sum = 0;
for(size_t divisor = 1; divisor < number; divisor++)
if(number % divisor == 0)
sum += divisor;
return (sum == number);
}


Y el programa principal también se puede mejorar un poco ya que en cada iteración estás llamando a la función dos veces seguidas de las cuales la primera no sirve ya que el valor de retorno se está perdiendo. En vez de usar <system("pause") es mejor que uses <cin.get()>.
Código (cpp) [Seleccionar]

int main(){
int limit;
cout << "Introduce el limite superior: ";
cin >> limit;

for(size_t number = 1; number <= limit; number++)
if(isPerfect(number))
cout << number << endl;
        cin.get();
}
#709
Antes de nada modifica tu mensaje e inserta tu código entre etiquetas de código GeSHi (encima del cuadro de texto hay un desplegable para elegir el lenguaje, C en este caso), sino es muy difícil de interpretar...

Ahora respecto a tu problema. Tienes algunos errores a la hora de leer variables con <scanf()> y creo que la mejor forma de implementar lo que quieres es usando una <struct>. Ahora te comento un poco cómo funciona porque imagino que no las has usado nunca. Están dirigidas a la programación orientada a objetos (POO) y consiste en almacenar distintas variables dentro de un nuevo tipo de variable que creas.
Imagina una persona que tiene nombre y edad. Para no guardar los datos por ahí sueltos, podemos crear una <struct Persona> y cada objeto/variable de tipo <Persona> tendrá un nombre (char[]) y una edad (int).

#define MAX_SIZE 20 // longitud maxima para el nombre
struct Persona{
    char nombre[MAX_SIZE];
    int edad;
}; // siempre acabado en ;


Ahora para crear un objeto/variable de tipo <Persona> hay que seguir los mismos pasos que para cualquier otro tipo de variable pero sustituyendo el tipo de variable (int/float/char/...) por "struct" + <nombre struct>. En este caso, "struct Persona <nombre variable>". Y para acceder a las variables que están guardadas dentro de <Persona> se utiliza el punto (.). Te pongo un ejemplo.

// creamos la struct como se ve arriba
int main(){
    struct Persona yo;
    printf("Introduce tu nombre: ");
    scanf("%s", yo.nombre); // recomendable usar fgets()
    printf("Introduce tu edad: ");
    scanf("%d", &yo.edad); // en el scanf() anterior tambien vale scanf("%s", &yo.nombre) pero no es necesario el &

    printf("Tu nombre es %s y tienes %d años\n", yo.nombre, yo.edad);
}


He usado <scanf()> para guardar almacenar ambas variables para que veas cómo se usa pero las cadenas de caracteres es mejor que las guardes usando <fgets()>. El inconveniente es que se guardará también el <Enter> y cada vez que muestres la variable, acabará con un salto de línea. Eso se puede arreglar pero creo que mejor más adelante para no meter muchas cosas nuevas de golpe.

Ahora tienes que implementar tu código usando este ejemplo como guía, por ejemplo, crear un array de personas... :silbar:
Si tienes alguna duda al respecto siempre puedes preguntar. Suerte :-X
#710
Siempre puedes usar una función externa  :-X:

// declaracion de la struct

int sumar(struct foo my_foo, int y){
    return my_foo.x + y;
}

int main(){
    struct foo my_foo;
    my_foo.x = 2;
    int suma = sumar(my_foo, 8); // suma = 10
}