PDA

Visualizza la versione completa : C++ stringhe vuote


cristina1996
19-04-2017, 11:27
Ciao a tutti, mi sono appena registrata sul forum.
Ho scritto un programma in C++, che salva dei dati letti da file in variabili inizializzate in una classe tramite una funzione di tipo 'set' ad esempio. Le variabili sono sia stringhe che interi e float. Se nella funzione che setta le variabili inserisco una stampa per controllare che la copia sia avvenuta, la stampa corretta. Se, invece, dichiaro una nuova funzione specifica, di tipo 'print', per verificare il contenuto delle variabili, i valori numerici sono corretti, ma le stringhe sono vuote.
Questo problema mi era gi successo e non riesco a capire perch: forse sbaglio a copiare il contenuto delle stringhe?
Ho provato ad allegare lo zip ma troppo grande, carico il file da leggere, se avete voglia di dare un'occhiata sareste gentilissimi.

La descrizione del programma la seguente.
Si legge un file (studentInfo.txt) in cui ogni riga contiene un nome, un cognome e un certo numero di interi; per ogni persona chiamo una classe (vettManipClass) che calcola massimo, minimo, deviazione standard e media del gruppo di interi relativi a quella persona. Nel main, ho controllato che i valori calcolati sono corretti. Poi, vorrei memorizzare ogni nome, cognome e valori calcolati, utilizzando due classi composte: Student, che contiene i 4 valori, nome e cognome, e Register, che contiene un vettore di classi Student.
Nel main c' una sorta di men che permette all'utente di scegliere cosa stampare a video (nome, cognome e media relativa, etc...)
Nel'output, ogni volta che provo a stampare le stringhe nomi e cognomi, sono vuote.

main.cpp

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <string>
#include "C:/Users/vettManipClass.hpp"
#include "Student.hpp"
#include "Register.hpp"
using namespace std;


int main()
{
string file_name; string line; string name; string surname; int n_exams; int val[20]; int i; int opt=0; int cont=0;
string out_name; string new_name, new_surname; int voto; int flag;


cout << "Insert the file name: ";
cin >> file_name;


ifstream myfile;
myfile.open(file_name.c_str());


if(!myfile) {
cerr << "Error! The file " << file_name << " doesn't exist.";
exit(EXIT_FAILURE);
}
while(getline (myfile, line)) {
istringstream is;
is.str(line);
is >> name >> surname >> n_exams;
is.clear();


getline (myfile, line);
is.str(line);
for(i=0; i<n_exams; i++) {
is >> val[i];
}
is.clear();




vettManipClass vettManipObject;
vettManipObject.setNumAndVett(n_exams, val);


Register registro;
registro.add_student(name, surname, vettManipObject.maxFunct(), vettManipObject.minFunct(), vettManipObject.averageFunct(), vettManipObject.devFunct(), cont);


cont++;




}
myfile.close();


while(opt!=4) {
cout << endl << "Please choose one of the following options :" << endl << "[1] Simple report" << endl << "[2] Detailed report" << endl << "[3] Check student" << endl << "[4] Quit" << endl;
cin >> opt;
switch (opt) // THIS IS A MENU WHERE THE USER CHOOSES THE OUTPUT
{
case 1 : {


Register registro;
registro.print_student(cont);
break; }


case 2 : {


cout << "Insert output file name: "; cin >> out_name;
Register registro;
registro.print_file(out_name);
break; }


case 3 : {
cout << "Insert name surname grade : ";
cin >> new_name >> new_surname >> voto;


Register registro;
flag = registro.ricerca(new_name, new_surname, voto);
switch (flag)
{
case 0:
cout << endl << "ERROR : no student named " << new_name << ' ' << new_surname << " was found !" << endl;
break;
case 1:
cout << endl << "no" << endl;
break;
case 2:
cout << endl << "ok" << endl;
break;
}
break; }




}
}


cout << endl << "END OF THE PROGRAM" << endl;
return 0;
}


Register.hpp


#define REGISTER_H#define MAX_STUDENTS 50
#include "Student.hpp"
using namespace std;


class Register
{
public:
Register();
virtual ~Register();


void add_student(string, string, int, int, float, float, int);
void print_student(int);
void print_file(string);
int ricerca(string, string, int);


protected:
private:
Student vett[MAX_STUDENTS];
int j; int lim; string _out_name;
int _flag; string _new_name; string _new_surname; int _voto;
};


#endif // REGISTER_H


Register.cpp


#include "Register.hpp"#include "Student.hpp"
#include <string>
#include <iostream>
using namespace std;


Register::Register()
{
//ctor
}


Register::~Register()
{
//dtor
}
void Register::add_student(string _nome, string _cognome, int _massimo, int _minimo, float _media, float _deviazione, int _cont)
{
vett[_cont] = Student(_nome, _cognome, _massimo, _minimo, _media, _deviazione);
//cout << endl << "cont = " << _cont << ' ' << _nome << ' ' << _cognome << ' ' << _massimo << ' ' << _minimo << ' ' << _media << ' ' << _deviazione << endl;
}
void Register::print_student(int lim)
{
for(j=0; j<lim; j++)
vett[j].Student::print();
}
void Register::print_file(string _out_name)
{
for(j=0; j<lim; j++)
vett[j].Student::printOnFile(_out_name);
}
int Register::ricerca(string _new_name, string _new_surname, int _voto)
{
_flag = 0;
for(j=0; j<lim && _flag==0; j++) {
_flag = vett[j].Student::controllo(_flag, _new_name, _new_surname, _voto);
}
return _flag;
}


Student.hpp


#ifndef STUDENT_H#define STUDENT_H
#include <string>
using namespace std;


class Student
{
public:
Student();
Student(string, string, int, int, float, float);
virtual ~Student();


void print();
void printOnFile(string);
int controllo(int, string, string, int);


string nome; string cognome; int massimo; int minimo; float media; float deviazione;


protected:
private:


int k; char c;
string _out_name;
int FLAG; string NAME; string SURNAME; int VOTO;


};


#endif // STUDENT_H


Student.cpp


#include "Student.hpp"#include <string>
#include <iostream>
#include <iomanip>
#include <ctype.h>
#include <fstream>
using namespace std;


Student::Student()
{
//ctor
}


Student::~Student()
{
//dtor
}
Student::Student(string _nome, string _cognome, int _massimo, int _minimo, float _media, float _deviazione)
{
nome = _nome;
cognome = _cognome;
massimo = _massimo;
minimo = _minimo;
media = _media;
deviazione = _deviazione;
}
void Student::print()
{
cout << endl;


for(k=0; nome[k]!='\0'; k++) {
c = toupper(nome[k]);
cout << c;
}
cout << ' ';
for(k=0; cognome[k]!='\0'; k++) {
c = toupper(cognome[k]);
cout << c;
}
cout << ' ';
cout << setprecision(4) << media << endl;


}
void Student::printOnFile(string _out_name)
{
ofstream fout;
fout.open(_out_name.c_str(), ios::app);
fout << nome << ' ' << cognome << ' ' << massimo << ' ' << minimo << ' ' << media << ' ' << setprecision(3) << deviazione << endl;
fout.close();


}
int Student::controllo(int FLAG, string NAME, string SURNAME, int VOTO)
{
if(nome==NAME && cognome==SURNAME) {
FLAG = 1;
if(VOTO<=media)
FLAG = 2;
}
return FLAG;
}

boots
19-04-2017, 13:59
C' voluto un po', ma alla fine credo di aver capito il problema: Ridichiari sempre registro. In questo modo lo sovrascrivi perdendo le stringhe (non l'oggetto, ma il "valore" ) visto che sono allocate nell'heap al contrario degli int che sono nello stack.


main (){
...
while(getline (myfile, line)) {
...
Register registro; // Lo dichiari ad ogni ciclo
vettManipClass vettManipObject;
}
...
case 1 : {
Register registro; // Lo ridichiari
registro.print_student(cont);
break; }
case 2 : {
cout << "Insert output file name: "; cin >> out_name;
Register registro; // Lo ridichiari anche qua
registro.print_file(out_name);
break; }
case 3 : {
cout << "Insert name surname grade : ";
cin >> new_name >> new_surname >> voto;
Register registro; // e qui
}


Dichiarali una sola volta all'inizio del main (non dentro un ciclo) e basta.

inoltre , non ti conviene tener traccia del numero degli studenti dentro Register?

cristina1996
19-04-2017, 14:15
C' voluto un po', ma alla fine credo di aver capito il problema: Ridichiari sempre registro. In questo modo lo sovrascrivi perdendo le stringhe (non l'oggetto, ma il "valore" ) visto che sono allocate nell'heap al contrario degli int che sono nello stack.

Dichiarali una sola volta all'inizio del main (non dentro un ciclo) e basta.


Oddio grazie!!! Che stupida... vero. E ho aggiustato anche il contatore degli elementi...
Grazie mille!!! Ti adoro :love: !! Sei gentilissimo, grazie per esserti preso la briga di aiutarmi.
Ti pagherei volentieri un caff!
Mi sono scervellata per giorni, sei un genio, grazie infinite! :yuppi:

boots
19-04-2017, 17:30
Di niente ... :ciauz:

Loading