Witam. Mam pewien problem. Mam do zrobienia projekt na laboratorium z programowania. Już jest prawie skończony jednak występuje kilka problemów. Podaję kod:
#include<iostream>
#include<cmath>
#include<conio.h>
#include<cstdlib>
#include<string>
#include<fstream>
#include<cstring>
#include<ctime>
#include<windows.h>
using namespace std;
string PL( const char * text )
{
std::string result;
for(; * text; text++ )
switch( * text )
{
case 'ą': result += static_cast < char >( 0xa5 ); break;
case 'ć': result += static_cast < char >( 0x86 ); break;
case 'ę': result += static_cast < char >( 0xa9 ); break;
case 'ł': result += static_cast < char >( 0x88 ); break;
case 'ń': result += static_cast < char >( 0xe4 ); break;
case 'ó': result += static_cast < char >( 0xa2 ); break;
case 'ś': result += static_cast < char >( 0x98 ); break;
case 'ż': result += static_cast < char >( 0xbe ); break;
case 'ź': result += static_cast < char >( 0xab ); break;
case 'Ą': result += static_cast < char >( 0xa4 ); break;
case 'Ć': result += static_cast < char >( 0x8f ); break;
case 'Ę': result += static_cast < char >( 0xa8 ); break;
case 'Ł': result += static_cast < char >( 0x9d ); break;
case 'Ń': result += static_cast < char >( 0xe3 ); break;
case 'Ó': result += static_cast < char >( 0xe0 ); break;
case 'Ś': result += static_cast < char >( 0x97 ); break;
case 'Ż': result += static_cast < char >( 0xbd ); break;
case 'Ź': result += static_cast < char >( 0x8d ); break;
default: result += * text; break;
}
return result;
}
struct odpowiedz
{
char tresc[30];
bool prawda;
};
struct pytania
{
int id_pytania;
char tresc_pytania[150];
odpowiedz odpowiedz1;
odpowiedz odpowiedz2;
odpowiedz odpowiedz3;
odpowiedz odpowiedz4;
};
#pragma pack(push, 1)
struct testowani
{
int id_testowanego;
char imie[20];
char nazwisko[20];
char pesel[11];
int wynik;
};
#pragma pack(pop)
void wyniki();
void wybor_testowanego();
void dodawanie_pytania();
void administrowanie();
void dodawanie_testowanego();
int menuGlowne();
int test(int);
void wpisywanieHasla();
char czyPoprawny(char pes[]);
void komunikat_o_malej_ilosci_pytan();
void zapisywanie_wyniku(int id_test,int wynik);
int main()
{
cout << PL("Witaj w teście z matematyki") << endl;
menuGlowne();
return 0;
}
int menuGlowne()
{
system("cls");
cout << PL("MENU GŁÓWNE") << endl;
cout << PL("1. Rozwiąż test") << endl << PL("2. Administruj danymi") << endl << PL("Inny klawisz -> Wyjdź z programu") << endl;
char decyzja;
decyzja=getch();
if (decyzja=='1')
wybor_testowanego();
else if (decyzja=='2')
wpisywanieHasla();
else return 0;
}
void wybor_testowanego()
{
testowani testowany;
char s_pesel[11];
cout << "Wybor testowanego" << endl;
cout << PL("Podaj swój PESEL: "); cin >> s_pesel;
ifstream plik("students.dat",ios::binary | ios::in);
if (plik.good()==false)
{
dodawanie_testowanego();
cout << "Nikogo nie ma w bazie" << endl;
} else
{
for(int i=0;;i++)
{
plik.seekg(sizeof(struct testowani)*i);
plik.read(reinterpret_cast<char*>(&testowany),sizeof(testowany));
if (strcmp(s_pesel, testowany.pesel)==0)
{
test(testowany.id_testowanego);
return;
}
if (plik.eof())
break;
}
}
plik.close();
cout << "Twojego peselu nie ma w bazie. Dodaj swoje dane do bazy." << endl;
dodawanie_testowanego();
}
void dodawanie_testowanego()
{
int dlugoscPliku;
fstream fs;
fs.open( "students.dat", ios::binary | ios::in );
if ( fs )
{
fs.seekg( 0, ios::end );
dlugoscPliku = fs.tellg();
fs.seekg( 0, ios::beg );
}
fs.close();
char poprawnoscPeselu;
testowani testowany;
float iloscRekordow;
fstream plik("students.dat",ios::binary | ios::out | ios::app | ios::in);
iloscRekordow=dlugoscPliku/sizeof(testowany);
cout << "Dodawanie testowanego" << endl;
testowany.id_testowanego=iloscRekordow+1;
cout << PL("Podaj imię: ");
cin >> testowany.imie;
cout << PL("Podaj nazwisko: ");
cin >>testowany.nazwisko;
cout << PL("Podaj PESEL: ");
do
{
cin >> testowany.pesel;
poprawnoscPeselu=czyPoprawny(testowany.pesel);
cout << "\n";
if (poprawnoscPeselu==0)
cout << PL("Podaj poprawny 11-cyfrowy PESEL!") << endl;
} while (poprawnoscPeselu==0);
testowany.wynik=0;
plik.write(reinterpret_cast<char*>(&testowany),sizeof(testowany));
plik.close();
cout << "\nNowy testowany dodany poprawnie!\n" << endl;
cout << PL("Naciśnij dowolny klaiwsz, aby wrócić do menu głównego...");
getch();
menuGlowne();
}
void dodawanie_pytania()
{
system("CLS");
pytania pytanie;
int dlugoscPliku;
ifstream fs;
fs.open( "qs.dat", ios::binary | ios::in );
if ( fs )
{
fs.seekg( 0, ios::end );
dlugoscPliku = fs.tellg();
fs.seekg( 0, ios::beg );
}
fs.close();
int iloscRekordow;
fstream plik("qs.dat",ios::binary | ios::out | ios::app | ios::in);
iloscRekordow=dlugoscPliku/sizeof(pytanie);
cout << "Dodawanie pytania" << endl;
pytanie.id_pytania==iloscRekordow+1;
cout << PL("Podaj treść pytania") << endl;
cin.sync();
cin.get( pytanie.tresc_pytania, 150 );
cout << PL("Podaj pierwszą odpowiedź") << endl;
cin.sync();
cin.get( pytanie.odpowiedz1.tresc, 30 );
cout << "Czy ta odpowiedz jest poprawna? 1 -TAK / 0 - NIE" << endl;
cin >> pytanie.odpowiedz1.prawda;
cout << PL("Podaj drugą odpowiedź") << endl;
cin.sync();
cin.get( pytanie.odpowiedz2.tresc, 30 );
cout << "Czy ta odpowiedz jest poprawna? 1 -TAK / 0 - NIE" << endl;
cin >> pytanie.odpowiedz2.prawda;
cout << PL("Podaj trzecią odpowiedź") << endl;
cin.sync();
cin.get( pytanie.odpowiedz3.tresc, 30 );
cout << "Czy ta odpowiedz jest poprawna? 1 -TAK / 0 - NIE" << endl;
cin >>pytanie.odpowiedz3.prawda;
cout << PL("Podaj czwartą odpowiedź") << endl;
cin.sync();
cin.get( pytanie.odpowiedz4.tresc, 30 );
cout << "Czy ta odpowiedz jest poprawna? 1 -TAK / 0 - NIE" << endl;
cin >> pytanie.odpowiedz4.prawda;
plik.write(reinterpret_cast<char*>(&pytanie),sizeof(pytanie));
plik.close();
administrowanie();
}
void administrowanie()
{
system("cls");
cout << "MENU ADMINISTRATORA" << endl;
cout << PL("Wybierz, co chcesz zrobić") << endl;
cout << PL("1. Dodaj pytanie \n2. Wyświetl wyniki \n3. Powrót do menu głównego \nInny klawisz -> Wyjdź") << endl;
char wybor;
wybor=getch();
if (wybor=='1')
dodawanie_pytania();
else if (wybor=='2')
wyniki();
else if (wybor=='3')
menuGlowne();
else exit(0);
}
void wpisywanieHasla()
{
string haslo;
string wpisane;
haslo="matematyka";
cout << PL("Podaj hasło dostępu... ");
do
{
cin >> wpisane;
cout << "\n";
if (wpisane!=haslo)
cout << PL("Nieprawidłowe hasło, podaj ponownie") << endl;
} while (wpisane!=haslo);
administrowanie();
}
int test(int id)
{
int los;
int iloscRekordow;
char odp;
int wynik_testu = 0;
pytania pytanie;
int dlugoscPliku;
int wylosowane_pytania[10];
system("cls");
fstream plik("qs.dat",ios::binary | ios::out | ios::app | ios::in);
if ( plik )
{
plik.seekg( 0, ios::end );
dlugoscPliku = plik.tellg();
plik.seekg( 0, ios::beg );
}
plik.close();
iloscRekordow=dlugoscPliku/sizeof(pytanie);
cout << PL("Ilość pytań ") << iloscRekordow << endl;
if (iloscRekordow<10)
komunikat_o_malej_ilosci_pytan();
else
{
cout << PL("Za chwilę zostanie wyświetlone 10 pytań.\nNa każde z nich odpowiedz wciskając odpowiadającą \nodpowiedzi literę na klawiaturze.\nNa pytanie możesz odpowiedzieć tylko raz,\nnie możesz wrócić do pytania, na które udzielono odpowiedzi!\n") << endl;
cout << PL("Aby rozpocząć test, naciśnij Enter...") << endl;
getch();
srand(time(NULL));
// LOSOWANIE 10 PYTAŃ
int ile_pytan = iloscRekordow;
int ile_juz_wylosowano=0;
int *wylosowane = new int[11];
bool losowanie_ok;
for (int i=1; i<=10; i++)
{
do
{
int liczba=rand()%11;
losowanie_ok=true;
for (int j=1; j<=ile_juz_wylosowano; j++)
{
if (liczba==wylosowane[j]) losowanie_ok=false;
}
if (losowanie_ok==true)
{
ile_juz_wylosowano++;
wylosowane[ile_juz_wylosowano]=liczba;
}
} while(losowanie_ok!=true);
}
for (int i=1;i<=10;i++) // PĘTLA WYPISUJĄCA 10 PYTAŃ
{
system("CLS");
cout << "Pytanie " << i <<"/10\n\n" << endl;
ifstream plik2("qs.dat",ios::binary | ios::in);
plik2.seekg(sizeof(struct pytania)*wylosowane[i]);
plik2.read(reinterpret_cast<char*>(&pytanie),sizeof(pytanie));
cout << pytanie.tresc_pytania << endl;
cout << "A. " << pytanie.odpowiedz1.tresc << endl;
cout << "B. " << pytanie.odpowiedz2.tresc << endl;
cout << "C. " << pytanie.odpowiedz3.tresc << endl;
cout << "D. " << pytanie.odpowiedz4.tresc << endl;
plik2.close();
odp=getch();
switch (odp)
{
case 'A':
case 'a':
{
if (pytanie.odpowiedz1.prawda)
wynik_testu++;
break;
}
case 'B':
case 'b':
{
if (pytanie.odpowiedz2.prawda)
wynik_testu++;
break;
}
case 'C':
case 'c':
{
if (pytanie.odpowiedz3.prawda)
wynik_testu++;
break;
}
case 'D':
case 'd':
{
if (pytanie.odpowiedz4.prawda)
wynik_testu++;
break;
}
}
}
cout << "Twoj wynik to: " << wynik_testu << endl;
if (wynik_testu>5)
{
cout << PL("TEST ZALICZONY!") << endl;
}
else
{
cout << PL("TEST NIEZALICZONY!") << endl;
}
zapisywanie_wyniku(id,wynik_testu);
cout << PL("\nAby powrócić do menu głównego, naciśnik dowolny klawisz...") << endl; getch();
menuGlowne();
}
}
void zapisywanie_wyniku(int id_test,int wynik)
{
testowani testowany;
ofstream plik1("students.dat",ios::binary | ios::out | ios::ate);
plik1.seekp(sizeof(testowany)*(id_test-1));
testowany.wynik=wynik;
plik1.write(reinterpret_cast<char*>(&testowany),sizeof(testowany));
plik1.close();
}
void wyniki()
{
system("CLS");
testowani testowany;
ifstream plik("students.dat",ios::binary | ios::in);
cout << "Wyniki:" << endl;
for (int i=0;;i++)
{
if (plik.eof())
break;
plik.seekg(sizeof(struct testowani)*i);
plik.read(reinterpret_cast<char*>(&testowany),sizeof(testowany));
cout << testowany.imie << " " << testowany.nazwisko << " PESEL: " << testowany.pesel << " WYNIK: " << testowany.wynik << endl;
}
plik.close();
cout << PL("\n\nNaciśnij dowolny klawisz, aby powrócić...") << endl; getch(); administrowanie();
}
char czyPoprawny(char pes[11])
{
int tab[11]={1,3,7,9,1,3,7,9,1,3};
int a,suma=0;
for(a=0;a<10;a++){
suma=suma+(tab[a]* (pes[a]-48));
}
suma=suma%10;
suma=10-suma;
suma+=48;
if (suma!=pes[10]) return 0;
else return 1;
}
void komunikat_o_malej_ilosci_pytan()
{
cout << PL("Nie można wylosować pytań, gdyż ich liczba w \nbazie jest mniejsza niż wymagane 10!") << endl;
cout << PL("Nastąpi powrót do Menu Głównego w celu dodania pytań") << endl;
Sleep(1000);
cout << "......." << endl;
Sleep(1000);
cout << "......" << endl;
Sleep(1000);
cout << "....." << endl;
Sleep(1000);
cout << "...." << endl;
Sleep(1000);
cout << "..." << endl;
Sleep(1000);
cout << ".." << endl;
Sleep(1000);
cout << "." << endl;
Sleep(1000);
menuGlowne();
}
Chodzi o to, że:
-
Po wykonaniu testu nie zapisuje wyniku. Tzn. wynik zapisuje jednak takie dane jak imię nazwisko i pesel kasuje. W funkcji wybor_testowanego, funkcja write zapisuje do struktury odczytane dane i powinna je cały czas przechowywać. Jednak w funkcji zapisywanie_wyniku zmieniam tylko wynik i zapisuję strukturę do pliku w miejsce starej. Jednak nie chce to działać. Jakieś sugestie jak to rozwiązać?
-
Wyświetlanie wyniku. Funkcja wyniki wyświetla wyniki. Jednak jeśli w bazie jest jeden testowany to wyświetla dwa razy ten rekord. Kiedy jest kilka to ostatni wyświetla dwa razy. Przeniosłem if z breakiem na początek pętli, żeby najpierw sprawdziło, czy koniec pliku, jednak nic to nie pomogło Tu również proszę o pomoc.
EDIT:
testowani testowany;
Dałem jako zmienną globalną i punkt pierwszy działa, dodaje tylko jeden znak do peselu nie wiem dlaczego. Jednak w projekcie nie można używać zmiennych globalnych więc muszę to osiągnąć inaczej.