średnia i oceny uczniów

0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 20 // maksymalna liczba studentow
#define LICZBA_ZADAN 6 // liczba ocenianych zadan
#define BUF_SIZE 256 // wielkosc bufora znakowego

char* dane[MAX]; // tablica przechowujaca imiona i nazwiska studentow (czyli wskazniki do tablic znakowych)
float oceny[MAX][LICZBA_ZADAN]; // tablica przechowujaca oceny

int indeks=0; // indeks pierwszej wolnej pozycji w dzienniku

// Funkcja dodajaca nowa osobe do dziennika
int dodaj(char* nowe_imie_nazwisko, float* nowe_oceny)
{
    char* kopia;
    int i;

    if(indeks<MAX-1) // sprawdzanie, czy jest jeszcze miejsce w tablicy
    {
        kopia=malloc((strlen(nowe_imie_nazwisko)+1)*sizeof(char)); // rezerwacja pamieci, adres zarezerwowanego obszaru wpisywany do wskaznika 'kopia'
        strcpy(kopia, nowe_imie_nazwisko); // kopiowanie ciagu znakowego 'nowe_imie_nazwisko' pod adres w 'kopia'
        dane[indeks]=kopia; // element dane[indeks] wskazuje teraz na to samo co 'kopia'

        for(i=0; i<LICZBA_ZADAN; i++)
            oceny[indeks][i]=nowe_oceny[i]; // przepisanie ocen

        return indeks++; // zwraca numer studenta
    }
    else
        return -1; // nie ma juz miejsca w tablicy

}

void wypisz_srednia()
{
    if(indeks==0)
    {
        printf("Brak danych!\n");
        return;
    }

    int i, j;
    float srednia=0;

    for(i=0; i<indeks; i++)
        for(j=0; j<LICZBA_ZADAN; j++)
        {
            srednia+=oceny[i][j];
        }
    srednia/=(indeks*LICZBA_ZADAN);

    printf("\nSrednia: %f\n\n", srednia);
}

void wypisz_srednia_ucznia()
{
    if(indeks==0)
    {
        printf("Brak danych!\n");
        return;
    }
    int i, j, k;
    float srednia=0;
    for(k=0;k<indeks;k++)
    {


    for(i=0;i<indeks;i++)
    {
        for(j=0;j<LICZBA_ZADAN;j++)
        {
        srednia=oceny[i][j]+srednia;
    }srednia=srednia/(indeks*LICZBA_ZADAN);
    printf("\nSrednia ucznia %s wynosi %-8f\n\n",dane[k], srednia);
    }
    }


}



// Funkcja wypisujaca oceny z zadan
void wypisz_oceny()
{
    if(indeks==0)
    {
        printf("Brak danych!\n");
        return;
    }

    int i, j;

    printf("\n");

    for(i=0; i<indeks; i++)
    {
        printf("%-30s ", dane[i]); // wypisanie imienia i nazwiska

        for(j=0;j<LICZBA_ZADAN; j++)
            printf("%1.1f ", oceny[i][j]); // wypisanie oceny

        printf("\n");
    }

    printf("\n");
}



// Funkcja zwalniajaca pamiec zaalokowana w 'dodaj'
void zwolnij()
{
    while(--indeks>=0)
        free(dane[indeks]); // zwalnianie pamieci zaalokowanej w funkcji dodaj

}


int main()
{
    char bufor[BUF_SIZE];
    float oceny[LICZBA_ZADAN];
    int i;

    int opcja, koniec=0;

    while(!koniec)
    {
        printf("[1] Wprowadzenie danych nowego studenta\n");
        printf("[2] Wypisanie ocen\n");
        printf("[3] Obliczenie sredniej\n");
        printf("[4] Obliczanie sredniej dla kazdego ucznia\n");
        printf("[0] Zakonczenie programu\n");

        printf("Wybierz opcje: ");
        scanf("%d", &opcja);

        while(getchar()!='\n'); // czyszczenie bufora wejsciowego

        switch(opcja)
        {
            case 1:
                printf("Wprowadz imie i nazwisko studenta: ");

                gets(bufor); // wczytanie pojedynczej linii

                for(i=0; i<LICZBA_ZADAN; i++)
                {
                    printf("Ocena z zadania %d: ", i+1);
                    scanf("%f", &oceny[i]);
                }

                dodaj(bufor, oceny);
                break;

            case 2:
                wypisz_oceny();
                break;

            case 3:
                wypisz_srednia();
                break;
            case 4:
                wypisz_srednia_ucznia();
                break;

            case 0:
            default:
                koniec=1;
                break;
        }

    }

    zwolnij(); //zwolnienie pamiecie zaalokowanej podczas pracy programu

    return 0;
}
 

Mam problem z częścią "wypisz srednia ucznia". Dla jednego ucznia mi działa ale jak wprowadzę ich więcej nie działa jak trzeba. Może ktoś wie gdzie popełniam błąd? Z góry dziękuje.

1

Ten kod nie zachęca do czytania. Weź przepuść przez jakiś formater.

for (k = 0; k < indeks; k++) {
    for (i = 0; i < indeks; i++) {
        for (j = 0; j < LICZBA_ZADAN; j++) {
            srednia = oceny[i][j] + srednia;
        }
        srednia = srednia / (indeks * LICZBA_ZADAN);
        printf("\nSrednia ucznia %s wynosi %-8f\n\n", dane[k], srednia);
    }
}

Pytanie 1: Dlaczego masz 2 pętle lecące po indeksach?
Pytanie 2: gdzie zerujesz średnią po wyliczeniu dla każdego ucznia?

0
for (k = 0; k < indeks; k++) {
    for (i = 0; i < indeks; i++) {
        for (j = 0; j < LICZBA_ZADAN; j++) {
            srednia = oceny[i][j] + srednia;
        }
        srednia = srednia / (indeks * LICZBA_ZADAN);
        printf("\nSrednia ucznia %s wynosi %-8f\n\n", dane[k], srednia);
        srednia =0;
    }
} 

srednia wyzerowałbym tak ? ale nie wiem co zrobić z tym indeksem ?

0

wypisuje imiona i nazwiska, ale zmieniłem kod na taki(za k wstawiłem i) i trochę poprawił ale nadal wartości średniej mi wychodzą 2 razy mniejsze.

	
for (i= 0; i < indeks; i++) {
    for (i = 0; i < indeks; i++) {
        for (j = 0; j < LICZBA_ZADAN; j++) {
            srednia = oceny[i][j] + srednia;
        }
        srednia = srednia / (indeks * LICZBA_ZADAN);
        printf("\nSrednia ucznia %s wynosi %-8f\n\n", dane[i], srednia);
        srednia =0;
    }
}  
0

Ok wykasowałem ją i rzeczywiście nic nie w kodzie nie zmieniała ale i tak program wartości mi złe podaje.

 for (i = 0; i < indeks; i++) {
        for (j = 0; j < LICZBA_ZADAN; j++) {
            srednia = oceny[i][j] + srednia;
        }
        srednia = srednia / (indeks * LICZBA_ZADAN);
        printf("\nSrednia ucznia %s wynosi %-8f\n\n", dane[k], srednia);
        srednia =0;
    }
  
0

Ok wykasowałem ją i rzeczywiście nic w kodzie nie zmieniała ale i tak program wartości mi złe podaje.

 for (i = 0; i < indeks; i++) {
        for (j = 0; j < LICZBA_ZADAN; j++) {
            srednia = oceny[i][j] + srednia;
        }
        srednia = srednia / (indeks * LICZBA_ZADAN);
        printf("\nSrednia ucznia %s wynosi %-8f\n\n", dane[i], srednia);
        srednia =0;
    } 
0

Krótki kurs "debuggowania":

for (i = 0; i < indeks; i++) {
    for (j = 0; j < LICZBA_ZADAN; j++) {
        printf("ocena: %f, ", oceny[i][j]);
        srednia = oceny[i][j] + srednia;
    }
    srednia = srednia / (indeks * LICZBA_ZADAN);
    printf("\nBylo %d zadan", LICZBA_ZADAN);
    printf("\nSrednia ucznia %s wynosi %-8f\n\n", dane[k], srednia);
    srednia = 0;
}

Pytanie: co robi indeks w wyliczeniu średniej?
Pytanie 2: co robi k w wypisywaniu średniej?
Jak nadal błędu nie będziesz w stanie znaleźć to wklej to co "debugger" wypluł.

0

Odp na pyt 1: Indeks okresla ilu mamy uczniów.
odp na pyt 2: zamiast k powinno być i.

0

Zależy od jednego ucznia, już rozumiem bład i mi działa nie potrzebnie dzieliłem przez iloczyn indeksu i liczby zadań

0

I mam do ciebie prośbę mógłbyś mi wyjaśnić na czym polega takie polecenie do tego zadania: mam wprowadzić taka modyfikację że ma być osobne wprowadzanie i przechowywanie imienia i nazwiska (np.: utworzyć tablice char* dane[MAX][2]).

0
char* dane[MAX];

Do tej pory miałeś jedną tablicę, czyli dane[i] to imię i nazwisko i-tego ucznia. A teraz ma być tablica tablic:

char* dane[MAX][2];

czyli dane[i][0] to jest powiedzmy nazwisko, a dane[i][1] to imię. Oczywiście cały kod trzeba przerobić, żeby obsłużył nową postać.

2

A nie możesz tego opakować w struktury, żeby się jakoś kupy trzymało?

1

no właśnie. Zamiast stosować trudne tablice to jak najszybciej poczytaj o strukturach, wskaźnikach i strdup :p

0
#include <iostream>
#include <list> // lista jednokierunkowa tez moze byc...
#include <string>

using std::string;
using std::cout;

typedef const std::string& sT;
namespace settings
{
constexpr size_t iloscZadan = 10;
}

enum status
{
    OK = 0,
    NIE_ZNALEZIONO_UCZNIA,
    ZBYT_WIELE_OCEN,
    UCZEN_JUZ_W_SYSTEMIE
};

class uczen
{
private:
    unsigned oceny[settings::iloscZadan];
    size_t iloscDodanychOcen;
public:
    string imie, nazwisko;
 uczen(sT imie_, sT nazwisko_) : iloscDodanychOcen(0), imie(imie_), nazwisko(nazwisko_) {}
 ~uczen() {}
 status dodajOcene(unsigned ocena)
 {
     if(iloscDodanychOcen == settings::iloscZadan) return ZBYT_WIELE_OCEN;
     oceny[iloscDodanychOcen] = ocena;
     ++iloscDodanychOcen;
     return OK;
 }
 float sredniaOcen()
 {
     float tmp(0.0f);
     for(unsigned x =0; x<iloscDodanychOcen; ++x)
     tmp += oceny[x];
return tmp/static_cast<float>(iloscDodanychOcen);
 }
};

typedef std::list<uczen>::iterator iT;

class szkola
{
    private:
    std::list<uczen> uczniowie;
   inline iT znajdzUcznia(sT nazwisko)
    {
        for(  iT u = uczniowie.begin(); u != uczniowie.end(); ++u)
           if(u->nazwisko == nazwisko) return u;

            return uczniowie.end();
    }
    public:
    status dodajOcene(sT nazwisko, unsigned ocena)
    {
    iT i = znajdzUcznia(nazwisko);
    if(i == uczniowie.end()) return NIE_ZNALEZIONO_UCZNIA;
    return i->dodajOcene(ocena);

    }

    status dodajUcznia(sT imie, sT nazwisko)
    {
        iT u = znajdzUcznia(nazwisko);
        if(u != uczniowie.end()) return UCZEN_JUZ_W_SYSTEMIE;
        uczniowie.push_back(uczen(imie, nazwisko));
        return OK;
    }
    float sredniaUcznia(sT nazwisko)
    {
        iT u = znajdzUcznia(nazwisko);
        if(u == uczniowie.end()) return 0.0f;
       return u->sredniaOcen();
    }
    float sredniaSzkoly()
    {
        float s(0.0f);
        for(auto u : uczniowie)
        {
            s+=u.sredniaOcen();
        }
        return s/uczniowie.size();
    }
};

string przetlumacz(status status)
{
    const string st[] = {
    {""}, // ok
    {"Nie znaleziono podanego Ucznia.\n"},
    {"Uczen posiada zbyt wiele ocen.\n"},
    {"uczen juz w systemie!\n"},
    };

    return st[status];
}

int main()
{
szkola szkola;
cout << przetlumacz(szkola.dodajUcznia("Adam", "Kowalski"));
cout << przetlumacz(szkola.dodajUcznia("Jan", "Nowak"));
cout << przetlumacz(szkola.dodajOcene("Nowak", 1));
cout << przetlumacz(szkola.dodajOcene("Nowak", 6));
cout << przetlumacz(szkola.dodajOcene("Kowalski", 6));
cout << "Srednia szkoly " << szkola.sredniaSzkoly();
}

Tak z nudów zrobiłem... może mały feedback? :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1