c- struktura

0

Witam

Mam problem ponieważ we funkcji void DodajOpisStudenta stworzyłem petle i po jej jednokrotnym wykonaniu petla zamiast zaczac sie od podaj nazwisko studenta to automatycznie przechodzi do podaj imie studenta, co moze byc tego przyczyna ?

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define ROZMIAR 5

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

} STUDENT; 


char WyborOpcji();
void WypiszListeStudentow();
void DodajOpisStudenta();
void ModyfikujOpisStudenta();
void UsunOpisStudenta(); 


int main() 
{
	


STUDENT Studenci[ROZMIAR];
char opcja='?';
printf("Program STUDENCI\n");

while(opcja != '0') {
switch(opcja) {
case '1': WypiszListeStudentow(Studenci[ROZMIAR]);
break;
case '2':DodajOpisStudenta(Studenci[ROZMIAR]);
break;
case '3': ModyfikujOpisStudenta(Studenci[ROZMIAR]);
break;
case '4': UsunOpisStudenta(Studenci[ROZMIAR]);
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");

break;
default:
break;

}
opcja=WyborOpcji("Podaj numer opcji: ");
}
}

char WyborOpcji(char prompt[]) {
char linia[80];
char opcja;
printf("%s", prompt);
 if(gets(linia)==NULL) return '\0';
return linia[0];
}
void WypiszListeStudentow() {
printf("Lista studentow:\n");
}
void DodajOpisStudenta(STUDENT tab[ROZMIAR]) 
{
int i;
printf("Dodawanie opisu studenta\n");

	for(i=0;i<ROZMIAR; i++)

     {
     puts("Podaj nazwisko studenta");
     gets(tab[i].Nazwisko);
	 puts("Podaj imie studenta");
     gets(tab[i].Imie);
     puts("Czy student ma zaleglosci");
     scanf("%h ",&tab[i].czyMaZaleglosci);
     puts("Podaj srednia ocen studenta");
     scanf("%1f ",&tab[i].SredniaOcen);
     }
}
void ModyfikujOpisStudenta() {
printf("Modyfikacja opisu studenta\n");
}
void UsunOpisStudenta() {
printf("Usuwanie opisu studenta\n");
}  
0
     scanf(" %29s",tab[i].Nazwisko);
     scanf(" %14s"tab[i].Imie);
     scanf(" %h",&tab[i].czyMaZaleglosci);
     scanf(" %lf",&tab[i].SredniaOcen);
1
case '2':DodajOpisStudenta(Studenci[ROZMIAR]);

Powinno być:

case '2':DodajOpisStudenta(Studenci);

Bo tak to podajesz funkcji element tablicy (który i tak notabene nie istnieje (off-by-one) ) zamiast adresu całej tablicy.

void DodajOpisStudenta(STUDENT tab[ROZMIAR])

Prawidłowo powinno być:

void DodajOpisStudenta(STUDENT tab[]) 
for(i=0;i<ROZMIAR; i++)
{
  puts("Podaj nazwisko studenta");
  gets(tab[i].Nazwisko);
  puts("Podaj imie studenta");
  gets(tab[i].Imie);
  puts("Czy student ma zaleglosci");
  scanf("%h ",&tab[i].czyMaZaleglosci);
  puts("Podaj srednia ocen studenta");
  scanf("%1f ",&tab[i].SredniaOcen);
}

Cała ta pętla powinna wyglądać np. tak:

for(i=0;i<ROZMIAR; i++) 
{
  puts("Podaj nazwisko studenta");
  fgets(tab[i].Nazwisko, 30, stdin);
  puts("Podaj imie studenta");
  fgets(tab[i].Imie, 15, stdin);
  puts("Czy student ma zaleglosci");
  scanf("%h ",&tab[i].czyMaZaleglosci);
  puts("Podaj srednia ocen studenta");
  scanf("%lf ",&tab[i].SredniaOcen);

  fflush(stdin) ;
}
1

zamiast short mozesz skorzystac z bool i do nazwiska/imienia użyć wskaźników a później strdup.

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

typedef struct {
	char *nazwisko;
	char *imie;
	bool ma_zaleglosci;
	float srednia_ocen;
} student_t;

do tego zamiast takich tablic ładniej użyć linked list albo jakieś dynamicznej tablicy.

1
Lord Darkstorm napisał(a):
  fflush(stdin) ;
}

To jest chyba niezgodne ze standardem

0
kkka napisał(a):

To jest chyba niezgodne ze standardem

Wprowadziłeś mnie lekko w zakłopotanie, ale dobrze zrobiłeś - przynajmniej nauczyłem się nowej rzeczy :).

To, co piszesz, to nie do końca prawda. Zerknąłem w dokumentację i okazuje się, że takie działanie jest implementation-defined - http://www.cplusplus.com/reference/cstdio/fflush/

In all other cases, the behavior depends on the specific library implementation. In some implementations, flushing a stream open for reading causes its input buffer to be cleared (but this is not portable expected behavior).

Szukałem alternatywnego rozwiązania i udało się. Zamiast walić w kodzie fflusha, wystarczy zrobić taki myk:

char c ;

// Wprowadzanie jakichś danych

while ( (c = getchar() ) != '\n') ;

Rozwiązanie znalazłem tu: http://4programmers.net/C/FAQ/Zabezpieczenie_przed_wpisywaniem_liter

0

Wprowadziłem zmiany o których napisaliście wyzej i dalej jest samo, czyli pomija mi po jednokrotnym wykonaniu petli wprowadzenie nazwiska tylko znowu przechodzi do imienia ,

0

Pokaz ten kod

0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define ROZMIAR 5

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

} STUDENT; 


char WyborOpcji();
void WypiszListeStudentow();
void DodajOpisStudenta();
void ModyfikujOpisStudenta();
void UsunOpisStudenta(); 


int main() 
{
	


STUDENT Studenci[ROZMIAR];
char opcja='?';
printf("Program STUDENCI\n");

while(opcja != '0') {
switch(opcja) {
case '1': WypiszListeStudentow(Studenci[ROZMIAR]);
break;
case '2':DodajOpisStudenta(Studenci);
break;
case '3': ModyfikujOpisStudenta(Studenci[ROZMIAR]);
break;
case '4': UsunOpisStudenta(Studenci[ROZMIAR]);
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");

break;
default:
break;

}
opcja=WyborOpcji("Podaj numer opcji: ");
}
}

char WyborOpcji(char prompt[]) {
char linia[80];
char opcja;
printf("%s", prompt);
 if(gets(linia)==NULL) return '\0';
return linia[0];
}
void WypiszListeStudentow(STUDENT tab[ROZMIAR]) 
{
	int i;
	printf("Lista studentow:\n");
	
	for(i=1;i<ROZMIAR; i++)
		{
			printf("%s \n",tab[i].Nazwisko);
			printf("%s \n",tab[i].Imie);
			printf("%h \n",tab[i].czyMaZaleglosci);
			printf("%.2f \n",tab[i].SredniaOcen);
		}

}
void DodajOpisStudenta(STUDENT tab[]) 
{
int i;
printf("Dodawanie opisu studenta\n");

	for(i=0;i<ROZMIAR; i++)

     {
     puts("Podaj nazwisko studenta");
     gets(tab[i].Nazwisko);
	 puts("Podaj imie studenta");
     gets(tab[i].Imie);
     puts("Czy student ma zaleglosci");
     scanf("%h ",&tab[i].czyMaZaleglosci);
     puts("Podaj srednia ocen studenta");
     scanf("%1f ",&tab[i].SredniaOcen);
     }
}
void ModyfikujOpisStudenta(STUDENT tab[ROZMIAR]) 
{
	int liczba;
	
	printf("Modyfikacja opisu studenta\n");
	printf("Podaj numer studenta ktorego opis chcesz modyfikowac \n");
	scanf("%d ",&liczba);
	{
	 puts("Podaj nazwisko studenta");
     gets(tab[liczba].Nazwisko);
	 puts("Podaj imie studenta");
     gets(tab[liczba].Imie);
     puts("Czy student ma zaleglosci");
     scanf("%h ",&tab[liczba].czyMaZaleglosci);
     puts("Podaj srednia ocen studenta");
     scanf("%1f ",&tab[liczba].SredniaOcen);
	}
}
void UsunOpisStudenta() {
printf("Usuwanie opisu studenta\n");
}   
0

Ja tu nie widze, zebys wprowadzil jakiekolwiek zmiany -.-

Zastosuj ta petle z getchar() ktora podal Lord Darkstorm

0

Teraz zmodyfikowałem kod i przy wypisywaniu listy studentów nie wyświetla mi pierwsze pozycji tylko jakieś śmieci

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define ROZMIAR 2

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

} STUDENT; 


char WyborOpcji();
void WypiszListeStudentow();
void DodajOpisStudenta();
void ModyfikujOpisStudenta();
void UsunOpisStudenta(); 


int main() 
{
	


STUDENT Studenci[ROZMIAR];
char opcja='?';
printf("Program STUDENCI\n");

while(opcja != '0') {
switch(opcja) {
case '1': WypiszListeStudentow(Studenci[ROZMIAR]);
break;
case '2':DodajOpisStudenta(Studenci[ROZMIAR]);
break;
case '3': ModyfikujOpisStudenta(Studenci[ROZMIAR]);
break;
case '4': UsunOpisStudenta(Studenci[ROZMIAR]);
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");

break;
default:
break;

}
opcja=WyborOpcji("Podaj numer opcji: ");
}
}

char WyborOpcji(char prompt[]) {
char linia[80];
char opcja;
printf("%s", prompt);
 if(gets(linia)==NULL) return '\0';
return linia[0];
}
void WypiszListeStudentow(STUDENT tab[ROZMIAR]) 
{
	int i;
	printf("Lista studentow:\n");
	
	for(i=0;i<ROZMIAR; i++)
		{
			printf("%s \n",tab[i].Nazwisko);
			printf("%s \n",tab[i].Imie);
			printf("%h \n",tab[i].czyMaZaleglosci);
			printf("%.2f \n \n",tab[i].SredniaOcen);
		}

}
void DodajOpisStudenta(STUDENT tab[ROZMIAR]) 
{
int i;
char c ;
printf("Dodawanie opisu studenta\n");

	
	for(i=0;i<ROZMIAR; i++)

     {
     	
     puts("Podaj nazwisko studenta");
     gets(tab[i].Nazwisko);
	 puts("Podaj imie studenta");
     gets(tab[i].Imie);
     puts("Czy student ma zaleglosci");
     scanf("%h ",&tab[i].czyMaZaleglosci);
     puts("Podaj srednia ocen studenta");
     scanf("%1f ",&tab[i].SredniaOcen);
     while ( (c = getchar() ) != '\n') ;
     }
     
}
void ModyfikujOpisStudenta(STUDENT tab[ROZMIAR]) 
{
	int liczba;
	char c ;
	
	printf("Modyfikacja opisu studenta\n");
	
	
	{
	puts("Podaj numer studenta ktorego opis chcesz modyfikowac \n");
	scanf("%d ",&liczba);
	
	 puts("Podaj nazwisko studenta");
     gets(tab[liczba].Nazwisko);
	 puts("Podaj imie studenta");
     gets(tab[liczba].Imie);
     puts("Czy student ma zaleglosci");
     scanf("%h ",&tab[liczba].czyMaZaleglosci);
     puts("Podaj srednia ocen studenta");
     scanf("%1f ",&tab[liczba].SredniaOcen);
     while ( (c = getchar() ) != '\n') ;  
	}
}
void UsunOpisStudenta(STUDENT tab[ROZMIAR]) 
{
	int numer;
	printf("Usuwanie opisu studenta\n");
	printf("Podaj numer osoby ktora chcesz usunac: \n");
	scanf("%c ",&numer);
	
	//tab[numer].Nazwisko="pusty";
	

}   
0

Bo nie umiesz przekazywac tablicy do funkcji...

Lord Darkstorm to tlumaczyl wczesniej

0

Człowieku czy umiesz czytać?

Lord Darkstorm napisał(a):
case '2':DodajOpisStudenta(Studenci[ROZMIAR]);

Powinno być:

case '2':DodajOpisStudenta(Studenci);

Bo tak to podajesz funkcji element tablicy (który i tak notabene nie istnieje (off-by-one) ) zamiast adresu całej tablicy.


Masz w tym kodzie jeszcze 5 błędów o których wyżej napisano oraz jeden o którym nie napisano ale non stop ci wypisuje kompilator.
Naucz się czytać zanim cokolwiek napiszesz na forum.

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