yang Temat założony przez niniejszego użytkownika |
problem z stringstream » 2011-05-27 23:35:40 Piszę prostą bazę danych, w której mam klasę Student i klasę Studenci, która posiada wektor obiektów klasy Student. Dane pobieram z pliku i w tym celu przeciążam operatory ">>" w obu klasach (jako funkcje zaprzyjaźnione) Mam to zrobione w następujący sposób:
w klasie Student:
istream & operator >>( istream & in, Student & s ) { in >> s.fNazwisko >> s.fImie >> s.fPESEL; string buf; getline( in, buf ); stringgstream ss( buf ); double ocena = 0.0; while( ss >> ocena ) s.fRekordOcen.push_back( ocena ); ss.str( string() ); cout << buf << endl; return in; }
i w klasie Studenci:
istream & operator >>( istream & in, Studenci & s ) { Student student; while( in >> student ) s.wszyscy.push_back( student ); return in; }
przykładowy plik:
Jakub aaa 234567 4 4 4
Tomasz dfa 4352345 2 2 2
Marcin dfas 909090 3 3 3
przeciążyłem również operatory "<<" i po wczytaniu z pliku, na konsoli dostaję zawsze dziwny efekt:
Jakub aaa 234567 4 4 4
Tomasz dfa 4352345 4 4 4 2 2 2
Marcin dfas 909090 4 4 4 2 2 2 3 3 3
i nie wiem jak sobie z tym poradzić, proszę o pomoc |
|
malan |
» 2011-05-28 00:03:41 ss.str( string() ); cout << buf << endl; ss.clear(); ss.sync(); Mogłem pomylić kolejność ;p |
|
DejaVu |
» 2011-05-28 00:06:45 Wywal couta:
/edit:
#include <iostream> #include <vector> #include <sstream> #include <cstdio> using namespace std;
struct Student { std::string fNazwisko; std::string fImie; std::string fPESEL; std::vector < double > fRekordOcen; };
istream & operator >>( istream & in, Student & s ) { in >> s.fNazwisko >> s.fImie >> s.fPESEL; string buf; getline( in, buf ); stringstream ss( buf ); double ocena = 0.0; while( ss >> ocena ) s.fRekordOcen.push_back( ocena ); ss.str( string() ); return in; }
void wypiszStudenta( const Student & s ) { cout << "Imie = " << s.fImie << endl; cout << "Nazwisko = " << s.fNazwisko << endl; cout << "PESEL = " << s.fPESEL << endl; cout << "Oceny = "; for( size_t i = 0; i < s.fRekordOcen.size(); i++ ) cout << s.fRekordOcen[ i ] << ", "; cout << endl; }
int main() { Student x[ 3 ]; for( int i = 0; i < 3; i++ ) cin >> x[ i ]; for( int i = 0; i < 3; i++ ) wypiszStudenta( x[ i ] ); return 0; }
Wejście:
a b c 1 2 3
d e f 4 5
g h i 6 7 8
Wyjście:
Imie = b
Nazwisko = a
PESEL = c
Oceny = 1, 2, 3,
Imie = e
Nazwisko = d
PESEL = f
Oceny = 4, 5,
Imie = h
Nazwisko = g
PESEL = i
Oceny = 6, 7, 8,
|
|
yang Temat założony przez niniejszego użytkownika |
» 2011-05-28 00:22:04 malan - niestety nie działa, próbowałem we wszelkich możliwych konfiguracjach i kolejnościach :)
deja vu -rzecz nie w coucie. Problem tkwi w tym jakie oceny wyświetla przy kolejnych studentach. Twój program działa, ale masz tylko jedną strukturę, a ja mam klasę, która posiada wektor obiektów klasy Student i dla obu klas przeciążam operatory, żeby wczytać cały plik naraz. No i ... wysypuje się :/ jeśli byś chciał to ja chętnie mogę wysłać Ci ten mój fenomen :) |
|
DejaVu |
» 2011-05-28 00:26:35 Może wszystkie dane dopisujesz do jednego wektora z ocenami? Zauważ, że wektor zawiera poprzednie oceny i dochodzą do niego nowe (tym samym wypisujesz np. tylko pierwszy wektor ocen o indeksie studenta nr 0).
/edit:
Poza tym mam całe 3 struktury ;p |
|
yang Temat założony przez niniejszego użytkownika |
» 2011-05-28 00:33:57 raczej nie. to jest kompletny program (bez inlcudów)
class Student
{
public:
typedef double Ocena;
typedef vector < Ocena > RekordOcen;
private:
string fNazwisko;
string fImie;
int fPESEL;
RekordOcen fRekordOcen;
public:
Student(void) : fNazwisko( "" ), fImie( "" ), fPESEL() {};
~Student(void) {};
//operatory "strumieniow"
friend ostream & operator << (ostream &, Student & );
friend istream & operator >> (istream &, Student & );
// Funkcje pomocnicze klasy - Getters & Setters
string GetNazwisko( void ) const { return fNazwisko; }
string GetImie( void ) const { return fImie; }
int GetPESEL( void ) const { return fPESEL; }
RekordOcen & GetRekordOcen( void ) { return fRekordOcen; } // zwracamy referencje do niestalego obiektu, wiec bez "const"
void SetNazwisko ( string & n ) { fNazwisko = n; }
void SetImie ( string & i ) { fImie = i; }
void SetPESEL ( int p ) { fPESEL = p; }
void DodajOcene( Ocena ocena ) { fRekordOcen.push_back( ocena ); }
int PodajLiczbeOcen( void ) const { return fRekordOcen.size(); }
bool ObliczOceneSrednia( Ocena & ocena_srednia )
{
if( fRekordOcen.size() == 0 ) return false;
double suma = 0.0;
for( int i = 0; i < fRekordOcen.size(); ++ i ) suma += fRekordOcen[ i ];
ocena_srednia = suma / (double)fRekordOcen.size(); // musimy "rzutowac" typy
return true;
}
};
ostream & operator << (ostream & out, Student & s)
{
double temp;
out << s.fNazwisko << " "
<< s.fImie << " "
<< s.fPESEL << " ";
for ( int i = 0; i < s.fRekordOcen.size(); i++ ) out << s.fRekordOcen[i] << " ";
out << endl;
return out;
}
istream & operator >> (istream & in, Student & s)
{
in >> s.fNazwisko
>> s.fImie
>> s.fPESEL;
string buf;
getline (in,buf );
stringstream ss(buf);
double ocena = 0.0;
while ( ss >> ocena ) s.fRekordOcen.push_back ( ocena );
ss.str( string() );
// cout << buf << endl;
ss.clear();
ss.sync();
return in;
}
class Studenci
{
public:
vector <Student> wszyscy;
public:
friend ostream & operator << (ostream &, Studenci & );
friend istream & operator >> (istream &, Studenci & );
};
istream & operator >> (istream & in, Studenci & s)
{
Student student;
while ( in >> student ) s.wszyscy.push_back ( student );
//{
// s.wszyscy.push_back ( student );
//}
return in;
}
ostream & operator << (ostream & out, Studenci & s)
{
for (int i = 0; i < s.wszyscy.size(); i++ )
{
out << s.wszyscy [ i ] << endl;
}
return out;
}
int main()
{
// GUI okno;
// okno.CloseBlackWindow();
// okno.CreateGUI();
Studenci a;
fstream strumien ("przyklad.txt");
strumien >> a;
cout << a;
getchar();
}
kod pewnie nie jest zbyt elegancki, ale prowadzący dał nam mały gotowiec, który później rozwijałem
i przepraszam, że te moje posty wyglądają jak wyglądają, ale nie za bardzo radzę sobie na forum :) |
|
absflg |
» 2011-05-28 00:41:46 Pojedynczy student działa. Zauważ jednak, że autor tematu stosuje też strukturę z wektorem studentów.
To ta struktura nie działa poprawnie.
istream & operator >>( istream & in, Studenci & s ) { Student student; while( in >> student ) s.wszyscy.push_back( student ); return in; }
(pierwszy post)
struct Studenci { std::vector < Student > wszyscy; };
(najprawdopodobniej chodzi o coś takiego)
@autor
Rozwiązanie jest proste: w operatorze istream>>Studenci przechowujesz wszystko w zmiennej student. Operator istream>>Student zmienia jego nazwisko imię i pesel, ale nie wymazuje starych ocen. |
|
yang Temat założony przez niniejszego użytkownika |
» 2011-05-28 00:55:23 Nie rozumiem.. za każdym razem jak wczytam całą strukturę "Student" to operator ">>" "uruchamia się" kolejny raz, czyli te wszystkie zmienne buf, stringstream itd. są tworzone na nowo i nie wiem jakim prawem cokolwiek w nich pozostaje. Poza tym dodaje kolejny element do wektora w klasie "Studenci" więc wszystko w nim powinno być czyste. Jeśli jesteś pewny co jest błędne w kodzie, to napisz mi proszę poprawne rozwiązanie. Cały kod jest dwa posty wyżej. Nasiedziałem się dziś nad tym bardzo długo i nie wymyśliłem. |
|
« 1 » 2 |