elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


  Mostrar Mensajes
Páginas: 1 ... 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 [62] 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 ... 102
611  Programación / Programación C/C++ / Re: Clases y objetos en C++ en: 25 Mayo 2019, 08:36 am
hola no te entiendo como quedaria el programa para que copile
Pues corrigiendo todos los errores que ha comentado @ivancea96 además de alguno más como que se está usando <costobase> para referirse al miembro privado de la clase cuando en realidad el miembro se llama <base> (bueno o eso es lo que se ha intentado).
Además el <set> y el <get> o se implementan dentro o fuera pero no en los dos sitios...
La verdad es que estoy asombrado con tal cantidad de errores y de este nivel... :o
612  Programación / Programación C/C++ / Re: Un programa con varias funciones y sin entradas en: 25 Mayo 2019, 08:24 am
El problema que tienes es que en el <main> estás pasando como parámetro el tipo de dato, cuando lo que tienes que pasar es el nombre del dato. El tipo solo se indica en el prototipo de la función y en su implementación.
Eso es algo muy muy básico.

En la función <analizarFichero(string)> si le estás pasando el nombre como parámetro, no pidas el nombre dentro de la función. Si lo vas a pedir dentro de la función no se lo pases como parámetro, no sirve de nada.
El <exit (1)> va sin espacio. Es una función que tiene un número como parámetro, no es lo mismo que un <return 1>.

En la función <pedirNumeroPositivo(ifstream)> tienes que pasar el fichero por referencia usando también &.

No te vuelvo a poner ejemplos de cada función porque ya lo hice en el mensaje anterior que publiqué.

Y sí, la función <mostrarPresentacionPrograma()> está bien. Es cierto que no tiene mucho sentido para un <cout> pero normalmente se suele usar para explicar el funcionamiento del programa o cómo hay que usarlo y en caso de que el usuario lo use mal pues se llama a la función de nuevo para que vea cómo se usa.
613  Programación / Programación C/C++ / Re: Un programa con varias funciones y sin entradas en: 23 Mayo 2019, 21:54 pm
No voy por orden, la verdad no sé por qué pero te voy comentando las funciones:
Citar
Código
  1. bool EsPrimo (int num) {
  2.    bool es_primo = false;  
  3.    for (int i = 2; i <= num-1; i++){
  4.       if (num % i == 0){
  5.           return false;
  6.       }
  7.    }
  8.    return num >= 2;
  9. }
En esta función estás creando una variable <bool es_primo = false> que no llegas a usar. Si la creas es para usarla y no usar más de 1 <return> en ese caso como ya te dije, la función quedaría así:
Código
  1. bool esPrimo(unsigned int numero){
  2.    bool es_primo = true; // suponemos que es primo
  3.    // for(size_t i = 2; i < numero and es_primo; ++i){ // se puede poner asi o como viene a continuacion
  4.    // el for o el while depende de si quieres/te dejan poner dos condiciones dentro del for
  5.    size_t i = 2;
  6.    while(i < numero and es_primo){ // mientras i < numero y numero sea primo
  7.        es_primo = (numero % i != 0); // es primo si el resto es distinto de 0
  8.        i++;
  9.    }
  10.    // llegas aqui cuando i == numero o cuando es_primo = false
  11.    return es_primo;
  12. }
Aquí ves que solo haces un <return> ya que usas la variable <es_primo> como condición de salida o de fin. En el momento que sabes que no es primo, terminas el bucle y retornas el valor que es <false> en ese caso. Si es primo hasta el final, retornas la misma variable que en este caso valdrá <true>.
La línea:
Código
  1. es_primo = (numero % i != 0);
Es lo mismo que poner:
Código
  1. if(numero % i == 0)
  2.    es_primo = false;
Por si así lo ves mejor.

En mi caso le estoy pasando como parámetro un <unsigned int numero>, es decir, que no tiene signo, por lo que siempre va a ser positivo. Si a esa función le pasas un <int> (puede ser negativo) te va a salir que cualquier número negativo es primo. Tenlo en cuenta. Esto lo puedes arreglar poniendo:
Código
  1. bool es_primo = num > 0;
  2. // donde pone
  3. bool es_primo = true;
Para considerar los negativos como no primos. Esto ya a tu gusto o al nivel de lo que te pidan.

Siguiente función:
Citar
Código
  1. int PedirNumeroPositivo(int num) {
  2.    string archivo;
  3.    while (!archivo.eof()){
  4.        archivo >> num;
  5.    }
  6. }
Aquí tienes varios problemas. Uno es que no puedes aplicar la función <eof()> a <archivo> que es un <string>. Además <num> no es algo que necesites pasar como parámetro. Y esa función retorna un <int> y ahí no retorna nada.
Para poder usar esta función, la función debe conocer el fichero (ifstream) <archivo>. Entonces eso necesitas pasarlo como parámetro. El <num> lo creas dentro de la función y lo retornas al finalizar esta.
Código
  1. int devolverNumero(ifstream &fichero){
  2.    int numero = 0; // le ponemos un 0 (o lo que queramos) para saber que cuando retorne ese valor es porque el fichero ha llegado a su fin
  3.    if(!fichero.eof())
  4.        fichero >> numero;
  5.    return numero;
  6. }
Esta función devuelve el siguiente número del fichero de entrada <fichero> o 0 si ha llegado al final del fichero. La posición en la que vas del fichero se guarda. Entonces cada vez que llames a esta función, devolverá el número siguiente al que retornó la última vez.
El tema de dónde cerrar el fichero te lo comento más abajo.

La siguiente función es la de <AnalizarFichero()>. Aquí tienes dos opciones que yo veo buenas y no muy complicadas:
  • Opción 1: Pasar el <ifstream> por referencia y devolver un <bool> de si se abrió correctamente o no.
Parámetros necesarios: ifstream &fichero (le podríamos pasar también el string con el nombre del fichero o se lo podemos pedir dentro de la función al usuario)
Retorno de la función: bool fichero_correcto
Código
  1. bool analizarFichero(ifstream &fichero){
  2.    string nombre_fichero;
  3.    bool fichero_correcto = true; // suponemos que se va a abrir bien...
  4.    // pedimos el nombre del fichero
  5.    fichero.open(nombre_fichero.c_str());
  6.    if(!fichero) // ...y si no es asi, cambiamos el valor a esa variable <fichero_correcto>
  7.        fichero_correcto = false;
  8.    return fichero_correcto;
  9. }
Si quieres pedir el nombre del fichero en el <main> y pasarlo como parámetro, te recomiendo que lo intentes tú. Incluso aunque no lo vayas a usar así, leyendo código no se aprende, se aprende escribiendo código porque ahí es dónde se ven los errores que comete uno y que en código ajeno no ve.
  • Opcion 2: Pasar el nombre como parámetro (o no pasar nada y pedirlo dentro de la función) y retornar un fichero abierto.
En este caso podemos hacerlo simple, recibimos el nombre como parámetro, creamos un <ifstream> con dicho nombre y lo devolvemos y se acabó.
Código
  1. ifstream abrirFichero(string nombre_fichero){
  2.    ifstream fichero(nombre_fichero.c_str()); // lo mismo que crear el fichero y hacer fichero.open(...)
  3.    // podemos hacer que si el fichero no es valido, termine el programa
  4.    if(!fichero)
  5.        exit(1); // exit termina el programa desde cualquier funcion en la que se ejecute. Pertenece a la libreria <cstdlib>
  6.    // y si no se cumple la condicion anterior, devolvemos el fichero
  7.    return fichero;
  8. }

También podemos pedirle nombres al usuario hasta que uno sea correcto:
Código
  1. ifstream abrirFichero(){
  2.    ifstream fichero; // aqui como no conocemos el nombre del fichero todavia usamos open(...) mas abajo
  3.    string nombre_fichero;
  4.    do{ // hacer esto de dentro...
  5.        // pedir nombre fichero y guardarlo en nombre_fichero
  6.        fichero.open(nombre_fichero);
  7.    }   while(!fichero); // ... mientras el fichero no se haya abierto
  8.    // llegamos aqui cuando por fin se ha abierto un fichero de entrada. Entonces lo devolvemos
  9.    return fichero;
  10. }

Puedes crear muchas alternativas más, como a ti se te ocurran. Así que te dejo que sigas investigando por tu cuenta. No te limites o copiar y pegar lo que yo he hecho porque así no vas a saber el porqué de cada cosa que hice, ni vas a ver los fallos que cometes al hacerlo tú.

Por último te dejo algún ejemplo de <main> para que veas como usar las funciones:
Código
  1. int main(){
  2.    // si le vamos a pasar el nombre del fichero como parametro, tendremos que declararlo aqui y pedirselo al usuario
  3.    // como abrir el fichero usando <ifstream abrirFichero()> (el ultimo ejemplo)
  4.    ifstream fichero = abrirFichero(); // sin parametros porque dentro de la funcion es donde le pediremos al usuario el nombre del fichero
  5.    // cuando estemos aqui el fichero ya esta bien abierto
  6.    // como sabemos segun la funcion <int devolverNumero(ifstream &fichero)> que hice arriba que retorna 0 cuando el fichero termina hacemos...
  7.    int numero = devolverNumero(fichero);
  8.    while(numero != 0){
  9.        cout << "El siguiente numero es: " << numero << endl;
  10.        if(esPrimo(numero)) // no hace falta poner == 1 o == true. Ya se entiende si no se pone nada que tiene que valer 1/true
  11.            cout << "El numero " << numero << " es primo" << endl;
  12.        else
  13.            cout << "El numero " << numero << " no es primo" << endl;
  14.        numero = devolverNumero(fichero);
  15.    }
  16.    // el fichero abierto es <fichero> entonces lo cerramos aqui
  17.    fichero.close(); // si se te olvida y no lo cierras tu, ya lo hace el programa al terminar
  18. }

Dale vueltas a todo esto que no es poco y practica. Es posible que me haya comido alguna palabra o me haya confundido al escribir algo pero no me apetece revisar todo el mensaje. Suerte :-X :-X
614  Programación / Programación C/C++ / Re: [?]Tengo problemas con los contadores de un videojuego en: 23 Mayo 2019, 08:12 am
No me voy a poner a revisar el código entero pero...
  • ¿Por qué mezclar C con C++? <printf()>/<cout> <scanf()>/<cin>...
  • ¿Por qué usar <conio.h>? Si lo necesitas para <getch()> tienes, <getchar()> (<cstdio>) o <cin.get()> (<iostream>) No es estándar y a muchos no nos dejará probar ese código al tener esa librería...
  • No uses <system(...)>. Usa <cin.get()> en vez de <system("pause")> y para limpiar la pantalla tienes la alternativa de hacer una función que pinte muchos saltos de línea.
  • <for> de la línea 30... ¿Por qué lo repites 2 veces la acción de asignar una palabra?
  • En la línea 18 yo diría que faltan punteros o... cada variable solo es un <char>?? ¿Por qué no usar <string>?

Para códigos de ya un cierto tamaño es recomendable empezar a modularizar un poco. Crea funciones que hagan cosas específicas y si tienes problemas con algo solo tienes que mirar la función que se encarga de eso y no todo el código.

Te dejo un pseudocódigo para que veas cómo lo puedes implementar.
Código:
nivel := 0
mientras nivel < NIVEL_MAX  and !has_perdido
    vidas := VIDAS_MAX - nivel // asi ya restas una vida al empezar cada nivel. Ten en cuenta que VIDAS_MAX > NIVEL_MAX
    mientras vidas > 0 and !acertado
        jugar()
    fin mientras
    has_perdido = !acertado // si has acertado no pierdes. Si te has quedado sin vidas, si
    si !has_perdido
        nivel := nivel + 1
    fin si
fin mientras
Se puede ahorrar alguna variable como <has_perdido> pero lo dejo así para que lo veas mejor.
615  Programación / Programación C/C++ / Re: Un programa con varias funciones y sin entradas en: 23 Mayo 2019, 02:34 am
Citar
Y luego una duda que me surge a la hora de hacer las funciones, mi profesor califica de "Mala práctica" el utilizar más de un Return en cada función, y en por ejemplo en la función EsPrimo (utilizada ya en el ejercicio anterior) he usado 2, pero no sabría como hacerla sin ambos ¿sabes porque es una mala práctica?
Se considera mala práctica en ocasiones porque puede que se te olvide algún <return>. Para evitar esto se suele usar una variable de tipo <bool> (la que tú habías creado en tu código "es_primo" pero que no usabas en la función).
Código
  1. bool esPrimo(unsigned int numero){
  2.    bool es_primo = true; // suponemos que es primo
  3.    size_t i = 2;
  4.    while(i < numero and es_primo){ // mientras i < numero y numero sea primo
  5.        es_primo = (numero % i != 0); // es primo si el resto es distinto de 0
  6.        i++;
  7.    }
  8.    // llegas aqui cuando i == numero o cuando es_primo = false
  9.    return es_primo;
  10. }

La función para mostrar la presentación del programa está casi bien. Está bien que sea de tipo <void> pero las funciones de tipo <void> no retornan nada. Siempre pones un <return 0>  en todas las funciones y eso solo se pone en el <main>. No tiene sentido hacer funciones que siempre devuelvan 0 y menos si son de tipo <void>.

La función <AnalizarFichero()> es mejor que le añadas algo más como una de las opciones que te di en el mensaje anterior:
Citar
Código
  1. bool ficheroAbiertoCorrectamente(string nombre_fichero);
  2. // Comprueba si se abrio bien y devuelve true si se abrio bien o false si no se abrio
  3. // Problema: Tenemos que abrir el fichero en la funcion para comprobar si se abrio bien y al salir de la funcion volver a abrirlo otra vez
  4.  
  5. ifstream abrirFichero(string nombre_fichero);
  6. // Comprueba si se pudo abrir el fichero y en caso de que si, lo devuelve abierto
  7. // Problema: y si no lo pudo abrir? Tendremos que hacer que el programa termine si no se pudo abrir
Yo por ejemplo usaría la segunda opción. Si se abre el fichero correctamente, lo devuelve como parámetro y sino termina el programa con <exit()> (de <cstdlib>).

La función <leerNumero()> la haría que reciba el fichero y devuelva el siguiente valor a leer.
Código
  1. int leerNumero(ifstream &fichero);
616  Programación / Programación C/C++ / Re: ayuda funcion buscar en: 22 Mayo 2019, 06:30 am
Aparte de los tantos <fflush(stdin)> que no deberían usarse, la función <gets()> que no debería usarse, la función <scanf()> para cadenas que tampoco debería usarse y los nombres de variables para nada específicos que supongo no vas a cambiar porque tú lo entiendes y con que lo entienda el que lo programa ya es suficiente... :silbar:
El problema lo tienes por usar unas veces <gets()> para guardar una cadena de caracteres (deberías usar <fgets()> mejor) y otras veces <scanf()>. <gets()> o su variante más segura <fgets()> guardan el enter del final como un salto de línea; mientras que el <scanf()> no guarda el salto de línea.
Por eso si tú escribes "Pepe" en un <gets()>, estás guardando "Pepe\n" mientras que si escribes "Pepe" en un <scanf()> estás guardando "Pepe". Por eso las cadenas no son iguales.
PD: La función <localizar()> no te va a funcionar como creo que esperas :silbar:
617  Programación / Programación C/C++ / Re: Un programa con varias funciones y sin entradas en: 21 Mayo 2019, 06:30 am
Para problemas diferentes mejor abrir un tema nuevo Por si a alguien más le interesa uno de los dos temas...
Lo primero que tienes que pensar es qué funciones quieres usar. Es decir, piensa quiero una función que haga tal cosa y luego piensa cómo implementarla, por ejemplo, quiero una función que me diga si el fichero se pudo abrir correctamente.
  • Qué necesito? Pasarle el nombre del fichero o el propio fichero (yo diría que mejor el nombre).
Código
  1. <retorno> ficheroAbiertoCorrectamente(string nombre_fichero);
Ahora miramos el retorno.
  • Qué va a hacer la función? Dos posibilidades:
- El fichero se abre correctamente.
- El fichero no se abre correctamente.
Idea 1:
Código
  1. bool ficheroAbiertoCorrectamente(string nombre_fichero);
  2. // Comprueba si se abrio bien y devuelve true si se abrio bien o false si no se abrio
  3. // Problema: Tenemos que abrir el fichero en la funcion para comprobar si se abrio bien y al salir de la funcion volver a abrirlo otra vez
  4.  
  5. ifstream abrirFichero(string nombre_fichero);
  6. // Comprueba si se pudo abrir el fichero y en caso de que si, lo devuelve abierto
  7. // Problema: y si no lo pudo abrir? Tendremos que hacer que el programa termine si no se pudo abrir
Si quieres puedes pensar tu propia alternativa, no tiene que ser una de esas dos, pero es para que te hagas una idea. Haz eso con cada función que vayas a crear. Piensa en grande, es decir, piensa en que cada función tiene que hacer una cosa específica y de la mejor forma posible.

Un truco es escribir el <main> de forma que se entienda a simple vista, por ejemplo:
Código
  1. int main(){
  2.    fichero = abrirFichero();
  3.    numero = leerNumero();
  4.    if(esPrimo(numero))
  5.        cout << numero << " es primo" << endl;
  6.    else
  7.        cout << numero << " no es primo" << endl;
  8. }
Y en base a eso crear las funciones añadiendo los parámetros que veas que necesitas, poniendo los retornos que necesitas, etc.
Tampoco te pases con las funciones, es decir, no empieces a meter una función dentro de otra y esta dentro de otra... Porque se hará demasiado lioso y no te valdrá la pena encapsular tanto. Tienes que encontrar el término medio. Piensa que una función es un trozo de código que puedes usar muchas veces en diferentes programas. Haz funciones que sean reutilizables.
Por ejemplo, puedes pensar en hacer una función que te muestre por pantalla si un número es primo o no, pero... y si en algún momento quieres saber si el número es primo pero no quieres mostrarlo por pantalla? (como en tu ejercicio anterior). Pues mejor hacer una función que te diga si es primo o no, sin mostrar nada y tú verás en cada situación si quieres mostrar por pantalla el resultado obtenido o no.

Comenta los avances que consigas empleando esta técnica y cuando pueda te seguiré ayudando. Suerte :-X
618  Programación / Programación C/C++ / Re: [ERROR] Id returned 1 exit denied en: 21 Mayo 2019, 03:58 am
Pon el código entre etiquetas de código GeSHi, sino no se ve la i entre corchetes...
Si en el <cout> del <for> estás poniendo la i entre corchetes después de la c, es decir:
Código
  1. cout << c[i];
No deberías de tener problemas. El código está bien. Puede ser porque lo hayas ejecutado antes y no hayas cerrado la ventana de ejecución. Prueba de nuevo y sino prueba a cerrar el IDE y volver a abrirlo y me cuentas.
(Estoy suponiendo que compilas con un IDE (netbeans, dev-c++, codeblocks,...) si no es así y estás compilando en línea de comandos (g++ programa.cpp -o programa) entonces pon la orden con la que estás compilando para poder ayudarte)
619  Programación / Programación C/C++ / Re: Ayuda de c++. en: 20 Mayo 2019, 17:49 pm
Espero que sea una duda sobre un ejercicio y no sea el típico mensaje pidiendo un ejercicio hecho. Además el foro está para tratar los temas de forma abierta y que te puedan ayudar todos y si luego alguien quiere leerlo, también le podrá servir de ayuda...
620  Programación / Programación C/C++ / Re: Un programa con varias funciones y sin entradas en: 18 Mayo 2019, 19:50 pm
Citar
Buenas!
YreX-DwX no entiendo muy bien el pseudocódigo que me pones para EsPrimo:
Código:
para i := 2 hasta numero-1
    si numero % i == 0
        return false
    fin si
fin para
return numero >= 2
¿Me la podrías explicar un poco más porfa?
Acabo de ver que le di la vuelta a lo que es ser primo en esa función por lo que no es correcta, ahora te la corrijo (está corregida en la cita)
Un número es primo si solo es divisible por si mismo y la unidad (no se considera al 1 primo). Entonces en vez de contar los divisores desde 1 hasta n y comprobar si el número de divisores es 2 (es primo) o es >2 (no primo); lo que hacemos es evitar esas dos divisiones. En lugar de empezar en 1 hasta n, empezamos en 2 hasta n-1. De esta forma se define como número primo todo aquel número que no es divisible por ningún número entre 2 y n-1 (excepto el 2 que es divisible por 2 y es primo).
El 1, en cambio, no es primo y el bucle no llega a ejecutarse para números < 3. Entonces en caso de que el bucle no se ejecute (esto sucede si los números son 1 o 2) tenemos que el 1 no es primo y el 2 sí.
Para tratar esa excepción usaremos <return (numero >= 2)> (date cuenta de que es una expresión booleana cuyo valor siempre es true/false, no son asignaciones).
Funcionamiento:
Se ejecuta el bucle (para números > 2) y si encuentra un divisor devuelve <false> (fallo mío que puse <true> lo voy a corregir en los otros mensajes) .
Si no encuentra un divisor podemos tener 2 motivos:
  • El número es < 3: {0, 1, 2} en cuyo caso el único primo es el 2
  • El número es > 2 y es primo: {3, 5, 7, 11, ...}
Entonces con la condición <return (numero >= 2)> obtendremos <true> (para el 2 y todos los primos) y <false> (para el 0 y el 1). Ahora sí está correcta la función y disculpas por el error... :-X

Citar
Y no me saca nada más que los dos primeros números perfectos usando los primos de Mersenne, o sea el 6 y el 28 nada mas ¿que es lo que tengo mal?
Eso es porque estás usando la variable <perf> para guardar la cantidad de números perfectos que llevas y el número perfecto actual. Entonces en el momento que el número perfecto supera el 10 (28 en este caso) termina. Usa dos variables distintas, una para el número perfecto y otra para la cantidad de números perfectos que llevas.
Páginas: 1 ... 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 [62] 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 ... 102
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines