olek1 napisał(a)
Przemęczyłem się przez ten program i napisałem.;d Działa raczej poprawnie, ale kod to taki napisałem, że chyba żal patrzeć.;d Mam tylko jeszcze jeden problem z tą linijką:
tab[x].skutecznosc = float(tab[x].rzuty)/float(tab[x].celne);
Źle rzutujesz.
tab[x].skutecznosc = (float)tab[x].rzuty / (float)tab[x].celne;
olek1 napisał(a)
Oraz u ostatniego zawodnika w zmiennej u przypisuje wartość 81 zamiast 8. U innych jest poprawnie.
Pokaż plik z danymi.
Co do Twojego kodu, to powinieneś wiedzieć, że funkcje nie gryzą. Wręcz przeciwnie, są bardzo użyteczne. Napisz sobie funkcję parsującą, zamiast powtarzać ten sam kod.
olek1 napisał(a)
FILE *wsk;
int i;
int j;
int n;
Czytelniej jest zapisać to tak:
int i, j, n, r, u, x, f, a, w;
Jeszcze lepiej jest użyć tablicy. Nie potrzebujesz jednak tworzyc tylu zmiennych. Możesz recyklować jedną.
olek1 napisał(a)
struct gracz tab[4] =
{
{0, "0", 0, 0, 0, 0, 0},
{0, "0", 0, 0, 0, 0, 0},
{0, "0", 0, 0, 0, 0, 0},
{0, "0", 0, 0, 0, 0, 0}
};
To jest zbyt rozwlekłe. Wyzeruj blok pamięci:
memset(tab, 0, rows * cols);
Lepszym rozwiązaniem byłoby tworzenie struktur dynamicznie i ich zerowanie:
s = (struct gracz*)calloc(1, sizeof(struct gracz));
Trzeba tylko pamiętać o zwalnianiu pamięci. Calloc() zaalokuje Ci pamięć pod strukturę i ją wyzeruje. Przy okazji prawidłowo zostanie zainicjowana tablica znaków, czyli bajtami zerowymi (pusty ciąg) zamiast wartością "0" (ciąg "0\0<śmieci>").
olek1 napisał(a)
if ((wsk = fopen("plik.dat", "r + b")) == NULL)
{
puts("Blad otwarcia pliku");
exit(1);
}
else
{ ...
Dla użytkownika bardziej istotna jest informacja dlaczego nie udało się otworzyć pliku. Z takim komunikatem zmuszasz go do zgadywania co jest źle.
W if'ie robisz exit(), zatem blok "else" jest tutaj niepotrzebny.
Zamiast exit(1) użyj "return 1" skoro jesteś w main().
olek1 napisał(a)
rewind(wsk);
for (x = 0; x < 4; x++)
Wczytujesz tylko 4 rekordy z pliku. Może warto byłoby pomyśleć o dynamicznej tablicy, lub (bardzo fajne ćwiczenie C przy okazji) liście powiązanej.
olek1 napisał(a)
i = 0; j = 0;
To możesz także zapisać tak:
i = j = 0;
olek1 napisał(a)
while(t[i] != ' ')
{
c[j] = t[i];
j++;
i++;
}
To prosty i skuteczny sposób, ale mam inną propozycję. Spróbuj wykorzystać funkcję strchr() do znalezienia danego znaku. Teoretycznie ona też skanuje ciąg w podobny sposób, ale jej użycie da zwięźlejszy kod. Samo kopiowanie możesz też wtedy przeprowadzić blokowo, a nie znak po znaku. strchr() wymaga zabawy wskaźnikami, co jest odrobinę bardziej złożone, więc jeśli podejmiesz rękawicę i będziesz miał problemy, to daj znać.
olek1 napisał(a)
n = strtol(c, &KONIEC, 10);
tab[x].numer = n;
Nie obsługujesz błędów. Jeśli w "c" znajduje się ciąg znaków niemożliwy do konwersji na wartość liczbową, strtol() zwraca 0. Warto obsłużyć takie przypadki jako błąd składni pliku z danymi. A jak rozpoznać "dobre" 0 od "złego"? Wskaźnik KONIEC powie Ci w którym miejscu tablicy wejściowej strtol() natknął się na zły bajt. Jeśli "KONIEC" (wskaźnik) ma taką samą wartość jak "c" (też wskaźnik), to znaczy że wartości w tablicy wejściowej są złe. Jeśli "KONIEC" wskazuje na bajt inny niż zerowy, to znaczy że na początku ciągu jest liczba, ale dalej jest już coś innego (dlatego najlepiej jest zestripować ciąg z białych spacji na końcu, bo z poczatkowymi strtol() sobie poradzi). Daj znać jeśli potrzebujesz przykładu.
olek1 napisał(a)
while(t[i] != ' ')
{
c1[j] = t[i];
j++;
i++;
}
Jeszcze jedna uwaga. Zlewasz możliwość wczytania "urwanej" linii. Jedziesz po tablicy w poszukiwaniu spacji, a powinieneś też szukać znaku nowej linii (koniec ciągu wczytanego przez fgets(); uciekasz z pętli) i bajtu zerowego (urwana ostatnia linia w pliku, błędne dane).
olek1 napisał(a)
if (fclose(wsk) != 0)
{
puts("Blad zamkniecia pliku");
exit(1);
}
W przypadku plików otwartych tylko do odczytu, błędy zamknięcia nie mają żadnego znaczenia, więc nie musisz tego sprawdzać. Nic złego się nie stanie jeśli z jakiegoś powodu (chociaż trudno mi sobie takowy wyobrazić w przypadku otwarcia RO) system nie będzie w stanie zamknąć pliku. Dane nie zostaną utracone, gdyż nic w buforze wyjściowym nie ma.
Krotko - dobrze Ci idzie, ale jest jeszcze kilka niewielkich niedociągnięć. W języku C trzeba pamiętać o sprawdzaniu błędów. Ignorowanie ich może prowadzić do problemów, nawet trudnych do zlokalizowania.