Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

problem z stringstream

Ostatnio zmodyfikowano 2011-05-28 09:29
Autor Wiadomość
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:
C/C++
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:
C/C++
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
P-33559
malan
» 2011-05-28 00:03:41
C/C++
ss.str( string() );
cout << buf << endl;
ss.clear();
ss.sync();
Mogłem pomylić kolejność ;p
P-33560
DejaVu
» 2011-05-28 00:06:45
Wywal couta:
C/C++
cout << buf << endl;

/edit:
C/C++
#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,
P-33561
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 :)
P-33562
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
P-33563
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 :)
P-33564
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.

C/C++
istream & operator >>( istream & in, Studenci & s )
{
    Student student;
    while( in >> student )
         s.wszyscy.push_back( student );
   
    return in;
}
(pierwszy post)

C/C++
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.
P-33565
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.
P-33566
« 1 » 2
  Strona 1 z 2 Następna strona