Bueno... encontrado el error, te comento lo que he hecho para que en otra ocasión puedas encontrar el problema tú solo.
Primero he comentado todo el contenido del main() excepto las primeras líneas hasta la llamada a LeerFichero() para ver si el problema estaba en esa función o en las siguientes. El error está ahí así que he ido a LeerFichero(). Una vez aquí, he añadido una línea para ver el contenido en cada iteración:
while ( getline(fich_in, linea) ){
cout << "\n#Contenido linea: " << linea << endl;
Estudiante e;
if ( StrToEstudiante(linea,e) )
v.push_back(e);
}
Si compilas y ejecutas verás que sólo se llega a mostrar el contenido de la primera línea del fichero por lo que el error está en la primera iteración. Vamos entonces a la función StrToEstudiante(). En esta función añadimos otra línea para ver cada token.
dato = ExtraerToken(texto);
cout << "#Dato extraido: " << dato << endl;
if ( dato.length() != 0 )
Vemos que todos los tokens se extraen correctamente por lo que el problema está en asignarValores(). Comentamos las líneas intermedias y las vamos descomentando una por una y ejecutando el programa con cada cambio. Aquí verás que el problema ocurre al descomentar setCurso() por lo que vamos ahí y... Resulta que estás haciendo una llamada recursiva a setCurso() desde setCurso() por lo que tenemos una recursividad infinita.
Te comento, asignValores() lo piden así en el enunciado. Lo de las funciones me lo apunto, pero vamos nace de que la tarea es una tontería y la he querido hacer rápido cpy/paste de funciones iguales. El problema se da al leer de fichero en el main. Con un main más sencillo no da error, como este por ejemplo:
EDIT: Una duda que me surge, ¿sería más óptimo utilizar los set en el constructor o modificar los atributos privados directamente?
El tema de copiar funciones que ya tienes al final hace que te limites a un estilo de programación siempre igual que puede resultar en ocasiones ineficiente. Cada situación puede ocasionar una solución mejor.
Y respecto a tu otra duda, diría que sí, es habitual en el constructor modificar directamente los atributos privados. Así generas menos dependencias y un error en un set() no va a hacer que todos tus objetos se creen de forma incorrecta. Además ya habrás visto que al ir llamando funciones dentro de funciones, cuando tienes un problema tienes que empezar a buscar hacia dentro y cuantas más tengas, más laborioso será llegar al final.
PD: Otro tip es que uses siempre nombres de variables significativos. Si otra persona tiene que leer tu código (y nunca sabes cuando puede pasar eso) o tú mismo cuando tengas códigos con mucho tiempo de desarrollo detrás y los veas después de mucho tiempo, siempre será más complicado saber qué es esto:
string dato;
unsigned int campo;
string id, a, n;
char s;
int e, h, w;
string tit;
int curs;
Que esto:
string dato;
unsigned int campo;
string id, apellidos, nombre;
char sexo;
int edad, height, weight;
string titulo;
int curso;