Usuwanie rekordu ze struktury

0

Witam, mam problem z funkcją usuwania ze struktury danych. cały kod programu wyglada tak:

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

typedef struct 
{
  char Nazwisko[30];
  char Imie[15];
  short czyMaZaleglosci;
  float SredniaOcen;
} STUDENT;

STUDENT Studenci[30]={{"Kowalski", "Jan", 0, 3.0}, {"Nowak", "Maciej", 1, 3.5},
{"Kowalczyk", "Marek", 0, 4.0}};

char WyborOpcji()
{
  char linia[80];
  char opcja;
  if(gets(linia)==NULL)
  return '\0';

  return linia[0];
}

void WypiszListeStudentow()
{
  int i;
  printf("\n");
  puts("WYPISYWANIE LISTY STUDENTOW: ");
  for(i=0;Studenci[i].Nazwisko[0]!='\0';i++)
    printf("Student nr. %d: %s %s, srednia ocen: %.1f, zaleglosci(1-TAK, 0-NIE): %d\n", i+1, Studenci[i].Imie, Studenci[i].Nazwisko, Studenci[i].SredniaOcen, Studenci[i].czyMaZaleglosci);
  printf("\n");
  puts("Funkcja wykonala swoja prace. Wybierz kolejna 'opcje': ");
}

void DodajOpisStudenta()
{
  int i;
  printf("\n");
  puts("DODAWANIE OPISU NOWEGO STUDENTA: ");
  for(i=0;Studenci[i].Nazwisko[0]!='\0';i++);
    printf("Wprowadz imie: ");
    scanf("%s", &Studenci[i].Imie);
    printf("Wprowadz nazwisko: ");
    scanf("%s", &Studenci[i].Nazwisko);
    printf("Wprowadz srednia ocen: ");
    scanf("%f", &Studenci[i].SredniaOcen);
    printf("Wprowadz zaleglosci: ");
    scanf("%d", &Studenci[i].czyMaZaleglosci);
  printf("\n");
  puts("Funkcja wykonala swoja prace. Wybierz kolejna 'opcje': ");
}

void ModyfikujOpisStudenta()
{
  int i, j;
  printf("\n");
  puts("MODYFIKOWANIE OPISU STUDENTA: ");
  for(i=0;Studenci[i].Nazwisko[0]!='\0';i++)
    printf("Student nr. %d: %s %s, srednia ocen: %.1f, zaleglosci(1-TAK, 0-NIE): %d\n", i+1, Studenci[i].Imie, Studenci[i].Nazwisko, Studenci[i].SredniaOcen, Studenci[i].czyMaZaleglosci);
  printf("Wybierz numer studenta do modyfiacji: ");
  scanf("%d", &j);
  printf("%s %s, srednia ocen: %.1f, zaleglosci(1-TAK, 0-NIE): %d\n", Studenci[j-1].Imie, Studenci[j-1].Nazwisko, Studenci[j-1].SredniaOcen, Studenci[j-1].czyMaZaleglosci);
  for(i=0;i<j;i++);
    printf("Zmodyfikuj imie: ");
    scanf("%s", &Studenci[i-1].Imie);
    printf("Zmodyfikuj nazwisko: ");
    scanf("%s", &Studenci[i-1].Nazwisko);
    printf("Zmodyfikuj srednia ocen: ");
    scanf("%f", &Studenci[i-1].SredniaOcen);
    printf("Zmodyfikuj zaleglosci: ");
    scanf("%d", &Studenci[i-1].czyMaZaleglosci);
  printf("\n");
  puts("Funkcja wykonala swoja prace. Wybierz kolejna 'opcje': ");
}

void UsunOpisStudenta()
{
  int i, j, k, x;
  printf("\n");
  puts("USUWANIE OPISU STUDENTA: ");
  for(i=0;Studenci[i].Nazwisko[0]!='\0';i++)
    printf("Student nr. %d: %s %s, srednia ocen: %.1f, zaleglosci(1-TAK, 0-NIE): %d\n", i+1, Studenci[i].Imie, Studenci[i].Nazwisko, Studenci[i].SredniaOcen, Studenci[i].czyMaZaleglosci);
  printf("Wybierz numer studenta do usuniecia: ");
  scanf("%d", &j);
  printf("%s %s, srednia ocen: %.1f, zaleglosci(1-TAK, 0-NIE): %d\n", Studenci[j-1].Imie, Studenci[j-1].Nazwisko, Studenci[j-1].SredniaOcen, Studenci[j-1].czyMaZaleglosci);
     for(x=0;x<30;x++)
       {
         if(x==j)
           {
             Studenci[x-1].Nazwisko==Studenci[29].Nazwisko;
             Studenci[x-1].Imie==Studenci[29].Imie;
             Studenci[x-1].czyMaZaleglosci=Studenci[29].czyMaZaleglosci;
             Studenci[x-1].SredniaOcen=Studenci[29].SredniaOcen;
             printf("Usunieto rekord %d.\n", x);
          }
       }
  printf("\n");
  puts("Funkcja wykonala swoja prace. Wybierz kolejna 'opcje': ");
}

main()
{
  char opcja='?';
  printf("Program STUDENCI\n");
  while(opcja!='0') {
    switch(opcja) {
      case '1':
        WypiszListeStudentow();
        break;
      case '2':
        DodajOpisStudenta();
        break;
      case '3':
        ModyfikujOpisStudenta();
        break;
      case '4':
        UsunOpisStudenta();
        break;
      case '?':
        printf("\n");
        printf("  1. Lista studentow\n");
        printf("  2. Dodanie pozycji\n");
        printf("  3. Modyfikacja pozycji\n");
        printf("  4. Usuniecie pozycji\n");
        printf("  0. Zakonczenie pracy\n");
        printf("  ?. Menu\n\n");
        printf("Wprowadz 'opcje': ");
        break;
      default:
        break;
    }
    opcja=WyborOpcji();
  }
  return 0;
}

W main() jest tylko switch i wywoływanie w nim kolejno funkcji: wypisywania listy studentów, dodawania nowego studenta, modyfikowania wpisu i usuwania wpisu. Funkcja usuwania "UsunOpisStudenta()" usuwa, czy raczej "zeruje" mi tylko zaległości i średnią ocen. Stąd moje pytanie. Jak usunąć wybrany przeze mnie rekord struktury tak, aby późniejsze wypisanie listy studentów odbyło się bez usuniętego rekordu? Pozostałe funkcje napisałem sam i działają jak należy. Z góry dziękuje za pomoc.

2

Pokaż kod, pewnie wystarczy użyć memmove.

Co do Twojej funkcji:

  1. funkcja usuwająca nie powinna nic wypisywać, tylko usuwać (SRP)
  2. w pętli porównujesz wszystkie indeksy dopóki nie znajdziesz szukanego (indeksu, nie wartości!) - to bzdura
  3. kod wygląda jakby się w ogóle nie kompilował. Dlaczego nikt nie odpowiada w moim wątku?
0

Ok, przesłałem na początku kod od góry do dołu.

  1. kod wygląda jakby się w ogóle nie kompilował.
    Kod się kompiluje..
2

Ach, faktycznie, masz tam porównanie zamiast przypisania (które by się nie kompilowało):

             Studenci[x-1].Nazwisko==Studenci[29].Nazwisko;
             Studenci[x-1].Imie==Studenci[29].Imie;
int findLastStudent()
{
	int arr_size = sizeof(Studenci)/sizeof(*Studenci);
	for(int i = 0; i < arr_size; ++i){
		if(!Studenci[i].Nazwisko)
			return i;
	}
	return arr_size;
}

void deleteStudent(int index)
{
	int numberOfStudents = findLastStudent();
	assert(index < numberOfStudents);
	memmove(Studenci + index, Studenci + index + 1, (numberOfStudents-index-1) * sizeof(*Studenci));
	memset(Studenci + numberOfStudents - 1, 0, sizeof(*Studenci));
}

http://melpon.org/wandbox/permlink/lbGJqGJiHlz8AXiZ
Pisane z palca, więc mogą być błędy

Przy okazji: zobacz ile warningów kompilator wywala. Popraw je. I tak ogółem, nie powinieneś stosować niepotrzebnie zmiennych globalnych.

0

Wszystko byłoby dobrze gdybym pisał w C++, ale program ma być w C, przepraszam, zapomniałem to dopisać. Jak odpalam program wyświetlają się dwa warningi dla linii z memmove i memset o treści

warning: incompatible implicit declaration of built-in function 'memmove' [enabled by default]

. Poza tym jak wybieram index studenta do usunięcia program się crashuje i kończy prace.

1

Przecież napisałem kod w C. Żeby użyć memmove polecam zainkludować odpowiednie nagłówki. memset i memmove są w <string.h>

0

Chodziło mi tylko o nie które wstawki, np: "int" w pętli for. Tak w ogóle to przepraszam mój błąd.. Teraz poprawiłem co trzeba i działa :) Chciałbym jeszcze dorobić coś takiego, żeby zamiast wpisywania pierwszego indeksu jako "0" wpisywać go jako "1"

1

Możesz po prostu odjąć jeden. A definicja zmiennej wewnątrz pętli jest w języku C od 17 lat.

0

Dziwne, bo jak zostawiłem int w pętli to program nie uruchomił się :/ Ok już wszystko działa. Dziękuje za pomoc!

1

Pewnie kompilujesz w trybie C89. Jeśli korzystasz z clanga/gcc to w parametrach kompilacji dopisz -std=c11

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