No voy por orden, la verdad no sé por qué pero te voy comentando las funciones:
bool EsPrimo (int num) {
bool es_primo = false;
for (int i = 2; i <= num-1; i++){
if (num % i == 0){
return false;
}
}
return num >= 2;
}
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í:
bool esPrimo(unsigned int numero){
bool es_primo = true; // suponemos que es primo
// for(size_t i = 2; i < numero and es_primo; ++i){ // se puede poner asi o como viene a continuacion
// el for o el while depende de si quieres/te dejan poner dos condiciones dentro del for
size_t i = 2;
while(i < numero and es_primo){ // mientras i < numero y numero sea primo
es_primo = (numero % i != 0); // es primo si el resto es distinto de 0
i++;
}
// llegas aqui cuando i == numero o cuando es_primo = false
return es_primo;
}
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:
es_primo = (numero % i != 0);
Es lo mismo que poner:
if(numero % i == 0)
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:
bool es_primo = num > 0;
// donde pone
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:
int PedirNumeroPositivo(int num) {
string archivo;
while (!archivo.eof()){
archivo >> num;
}
}
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.
int devolverNumero(ifstream &fichero){
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
if(!fichero.eof())
fichero >> numero;
return numero;
}
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
bool analizarFichero(ifstream &fichero){
string nombre_fichero;
bool fichero_correcto = true; // suponemos que se va a abrir bien...
// pedimos el nombre del fichero
fichero.open(nombre_fichero.c_str());
if(!fichero) // ...y si no es asi, cambiamos el valor a esa variable <fichero_correcto>
fichero_correcto = false;
return fichero_correcto;
}
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ó.
ifstream abrirFichero(string nombre_fichero){
ifstream fichero(nombre_fichero.c_str()); // lo mismo que crear el fichero y hacer fichero.open(...)
// podemos hacer que si el fichero no es valido, termine el programa
if(!fichero)
exit(1); // exit termina el programa desde cualquier funcion en la que se ejecute. Pertenece a la libreria <cstdlib>
// y si no se cumple la condicion anterior, devolvemos el fichero
return fichero;
}
También podemos pedirle nombres al usuario hasta que uno sea correcto:
ifstream abrirFichero(){
ifstream fichero; // aqui como no conocemos el nombre del fichero todavia usamos open(...) mas abajo
string nombre_fichero;
do{ // hacer esto de dentro...
// pedir nombre fichero y guardarlo en nombre_fichero
fichero.open(nombre_fichero);
} while(!fichero); // ... mientras el fichero no se haya abierto
// llegamos aqui cuando por fin se ha abierto un fichero de entrada. Entonces lo devolvemos
return fichero;
}
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:
int main(){
// si le vamos a pasar el nombre del fichero como parametro, tendremos que declararlo aqui y pedirselo al usuario
// como abrir el fichero usando <ifstream abrirFichero()> (el ultimo ejemplo)
ifstream fichero = abrirFichero(); // sin parametros porque dentro de la funcion es donde le pediremos al usuario el nombre del fichero
// cuando estemos aqui el fichero ya esta bien abierto
// como sabemos segun la funcion <int devolverNumero(ifstream &fichero)> que hice arriba que retorna 0 cuando el fichero termina hacemos...
int numero = devolverNumero(fichero);
while(numero != 0){
cout << "El siguiente numero es: " << numero << endl;
if(esPrimo(numero)) // no hace falta poner == 1 o == true. Ya se entiende si no se pone nada que tiene que valer 1/true
cout << "El numero " << numero << " es primo" << endl;
else
cout << "El numero " << numero << " no es primo" << endl;
numero = devolverNumero(fichero);
}
// el fichero abierto es <fichero> entonces lo cerramos aqui
fichero.close(); // si se te olvida y no lo cierras tu, ya lo hace el programa al terminar
}
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