Trochę bez sensu. Po co warunek
while(!czy_doskonala(n))
Jeśli dobrze rozumiem, chcesz sprawdzić każdą z podanych liczb. Jednakże Ty sprawdzasz w warunku, czy liczba, która już została sprawdzona jest doskonała. I jeśli nie jest, to kontynuujesz. Ale jeśli jest doskonała, to wychodzisz z pętli nie dając nawet możliwości sprawdzenia innych liczb. Ponadto w Twoim programie można wpisywać tyle liczb, ile się chce, o ile nie są doskonałe.
Ja bym zamienił to na:
while(i > 0) // lub po prostu na while(i)
{
Twoje instrukcje;
i--;
}
W dodatku widzę, że na koniec podajesz ilość liczb doskonałych odwołując się do funkcji sprawdzającej, czy podana liczba jest doskonała. To nie ma najmniejszego sensu.
Zainicjalizuj zmienną odpowiadającą za trzymanie informacji o ilości liczb doskonałych i pod koniec ją wyświetl.