Problema.
Sospecho que el problema es pedir un millón de std::string
en memoria automática:
#define DIM 1000000
// ...
string palabras[DIM];
Las variables que declaras de manera automática (sin utilizar el operador new
) van a parar a la pila. La pila tiene un espacio limitado que cambia según la implementación y la configuración del compilador pero suele ser de unos pocos kilobytes.
En cambio, si un std::string
(vacío) ocupa unos 32 bytes y pides un millón de ellos, estarás pidiendo 32 megabytes (un valor muy por encima del límite de la pila) lo cuál provoca un error en tiempo de ejecución dando lugar al comportamiento que describes:
al ejectutarlo ni siquiera aparece en pantalla lo de pedir el nombre de los ficheros, es decir falla directamente sin ejecutar si quiera la función principal.
Ya que al momento de entrar en main
debe hacer la solicitud de memoria de las variables que contiene y la tercera de esas variables desborda la pila.
Solución.
En lugar de usar memoria automática, usa un contenedor (que internamente usa memoria dinámica), puedes consultar aquí qué contenedor se ajusta a tus necesidades, yo te pondré un ejemplo con std::list
y modernizaré un poco tu código:
Propuesta:
Puedes ver el código funcionando en Try it online!.
#include <fstream>
#include <iostream>
#include <string>
#include <list>
// No usaremos memoria automática, así que esto es innecesario
// vvvv
// #define DIM 1000000
using namespace std;
using list_string = list<string>;
/*
el argumento 'nfich' es un string pasado por referencia constante porque:
- Referencia: Evitamos copiar su contenido.
- Constante: No pretendemos modificar su contenido.
el argumento 'palabras' es un lista_string pasado por referencia porque:
- Referencia: Pretendemos modificar su contenido dentro de la función.
No necesitamos que devuelva los elementos leidos porque la lista ya nos informa de su tamaño.
*/
void CopiaFichero(const string &nfich, list_string &palabras);
/*
el argumento 'nfichero' es un string pasado por referencia constante porque:
- Referencia: Evitamos copiar su contenido.
- Constante: No pretendemos modificar su contenido.
el argumento 'palabras' es un lista_string pasado por referencia constante porque:
- Referencia: Evitamos copiar su contenido.
- Constante: No pretendemos modificar su contenido.
No pasamos una variable con la cantidad de elementos porque la lista ya nos informa de ello.
*/
void RellenaFichero(const string &nfichero, const list_string &palabras);
// En C++ las funciones que no reciben parámetros se definen con paréntesis vacíos
int main ()
{
string norigen, ndestino;
list_string palabras;
cout << " Introduzca el nombre del archivo origen: ";
getline(cin, norigen);
cout << endl;
cout << " Introduzca el nombre del archivo destino: ";
getline(cin, ndestino);
CopiaFichero(norigen, palabras);
RellenaFichero(ndestino, palabras);
return 0;
}
void CopiaFichero(const string &nfich, list_string &palabras)
{
/* No hace falta llamar a .open(), pasando al constructor
un nombre de archivo lo abre al construirse. */
ifstream fichero{nfich};
// Un bucle sobre .eof() es incorrecto (ver notas al final)
// while(fichero.eof())
// Cuando 'fichero' equivalga a 'false' se habrá acabado la lectura.
for (string palabra; fichero; getline(fichero, palabra))
palabras.push_back(palabra);
/* No hace falta llamar a .close(), cuando se acaba la función
se llama automáticamente. */
}
void RellenaFichero(const string &nfichero, const list_string &palabras)
{
/* No hace falta llamar a .open(), pasando al constructor
un nombre de archivo lo abre al construirse. */
ofstream fichero{nfichero};
/* Puedes usar un for de rango, sin necesidad de usar una
variable de contador.
*/
for (const auto &palabra : palabras)
fichero << palabra << endl;
/* No hace falta llamar a .close(), cuando se acaba la función
se llama automáticamente. */
// No hace falta llamar 'return' para acabar una función.
// return;
}
No uses EOF en un while.