Seřazení dynamického pole struktur (studentů) – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Seřazení dynamického pole struktur (studentů) – C / C++ – Fórum – Programujte.comSeřazení dynamického pole struktur (studentů) – C / C++ – Fórum – Programujte.com

 

Horracio
~ Anonymní uživatel
3 příspěvky
7. 4. 2016   #1
-
0
-

Dobrý večer, při spuštění mého kódu a zadání názvu souboru mi vyskočí chyba program ......exe přestal pracovat. Kód jsem si procházel několikrát a chybu nemohu najít. Překladač žádný error ani warning nevyhazuje.(používám CodeLite s TDM-GCC)

Jen kdyby náhodou, vstupní soubor vypadá nějak takhle:

Jarmila Adamkova 36
Jiri Lapcik 22
Milan Petru 12.7
Milena Novakova 37.5

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

FILE *vstup;

typedef struct 
{
	char * Jmeno;
	char * Prijmeni;
	float znamka;
	} Student;
	
	int porovnejZnamky(float a, float b){
		if (a<b) return -1;
		if (a>b) return 1;
		return 0;
		};
		
		
int porovnejStudenty(const void *n1,const void *n2){  
		if ((strcmp (((Student*)n1)->Prijmeni,((Student*)n2)->Prijmeni))==0) { 
				if ((strcmp (((Student*)n1)->Jmeno,((Student*)n2)->Jmeno))==0) {
					porovnejZnamky(((Student*)n1)->znamka,((Student*)n2)->znamka);
					}
					
				else return strcmp (((Student*)n1)->Jmeno,((Student*)n2)->Jmeno); 
			}
		else return strcmp (((Student*)n1)->Prijmeni,((Student*)n2)->Prijmeni); 
		};

Student *poleStudentu;

int main(int argc, char **argv)
{	
	
	char soubor[256];
	int p = 255;
	
	if (argc>1){
				
				vstup = fopen(argv[1], "r");
				if (vstup == NULL){
							printf("\nVstupni soubor nelze otevrit\n");
							return 1;
							}
				}
				
	else{
			printf("\nZadejte nazev vstupniho souboru: ");
			gets(soubor);
			vstup = fopen(soubor, "r");
			if (vstup == NULL){
							printf("\nVstupni soubor nelze otevrit\n");
							return 1;
							}
		}

	poleStudentu = (Student *) malloc(10 * sizeof(Student));
	if(poleStudentu == NULL) {
            printf("Nedostatek pameti!\n");
			getchar();
            exit(1);
        }

	while(1){
	for (int i = 0; i < p; i++){
	if (i%10==0){ 
	poleStudentu = (Student*)realloc(poleStudentu, (i+10) * sizeof(Student));}
		if(poleStudentu == NULL) {
            printf("Nedostatek pameti!\n");
			getchar();
            exit(1);
        }
	if(fscanf(vstup, "%s %s %f", poleStudentu[i].Jmeno , poleStudentu[i].Prijmeni , &poleStudentu[i].znamka) == EOF){
			p = 0;}
	
	}}

	int pocetPrvku=sizeof(poleStudentu)/sizeof(Student);
	
	qsort(poleStudentu, pocetPrvku, sizeof(Student), &porovnejStudenty);
	
		printf("Serazeni studenti: \n");
	for (int i = 0; i < pocetPrvku; i++){
	printf("\n%s %s %0.2f", poleStudentu[i].Jmeno, poleStudentu[i].Prijmeni, poleStudentu[i].znamka);}
		
		free(poleStudentu);
		getchar();
		return 0;
		
		
}
Nahlásit jako SPAM
IP: 77.92.207.–
KIIV
~ Moderátor
+43
God of flame
7. 4. 2016   #2
-
0
-

To byva vetsinou zpusobenou spatnou praci s pameti.

Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV
~ Moderátor
+43
God of flame
7. 4. 2016   #3
-
0
-

No po 10 minutach preformatovavani a dalsich 5 minutach WTF - mas tam peknou hromadu chyb:

1) ve strukture mas  char * Jmeno, char * Prijmeni - jsou to jen pointery ukazujici kdo vi kde. Bud musis alokovat pamet, nebo pouzit pole!

2)  sizeof u poleStudentu vrati 4 nebo 8 (podle pouzite architektury procesoru)

  // sizeof(Student*) / sizeof(Student)  nevesti nic dobreho. Pri trose stesti to bude jen 4/12 (proste nula)
  int pocetPrvku=sizeof(poleStudentu)/sizeof(Student);

a tak dale

Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Horracio
~ Anonymní uživatel
3 příspěvky
7. 4. 2016   #4
-
0
-

#2 KIIV

Trochu jsem to pozměnil v téhle části, kde jsem myslel, že by mohl být zakopaný pes, ale bohužel.

Alespoň nějaký konkrétnější tip, v čem by to mohlo být ? 

poleStudentu = (Student *) calloc(100, sizeof(Student));
	if(poleStudentu == NULL) {
            printf("Nedostatek pameti!\n");
			getchar();
            exit(1);
        }

	while(1){
		for (int i = 0; i < p; i++){
			if(fscanf(vstup, "%s %s %f", poleStudentu[i].Jmeno , poleStudentu[i].Prijmeni , &poleStudentu[i].znamka) == EOF){
				p = 0;}
	
	}}

	int pocetPrvku=sizeof(poleStudentu)/sizeof(Student);
	
	poleStudentu = (Student*)realloc(poleStudentu, pocetPrvku * sizeof(Student));
		if(poleStudentu == NULL) {
            printf("Nedostatek pameti!\n");
			getchar();
            exit(1);
        }
	
	qsort(poleStudentu, pocetPrvku, sizeof(Student), &porovnejStudenty);
Nahlásit jako SPAM
IP: 77.92.207.–
KIIV
~ Moderátor
+43
God of flame
7. 4. 2016   #5
-
0
-

pro zacatek fscanf nacita na nejakou nahodnou adresu pameti... to je to, co jsem zminoval u te struktury

ale problemu tam bude daleko vic, si s tim chvili hraju a furt to ani zdaleka nefunguje

proc je tam vubec while (1) {  ???

Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV
~ Moderátor
+43
God of flame
7. 4. 2016   #6
-
0
-

 Trosku lepsi a mozna i funkcni:

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

FILE *vstup;

typedef struct {
  char    Jmeno[80]; // jen pointer neni dobry napad, musis alokovat pamet i pro tyhle retezce
  char Prijmeni[80]; // kdyz uz, tak aspon pole
  float  znamka;
} Student;
  
int porovnejZnamky(float a, float b) {
  if (a<b) return -1;
  if (a>b) return 1;
  return 0;
};

// male vylepseni (netestovano, mozna bude i fungovat):
int porovnejStudenty(void const * n1, void const * n2) {
  int tmp = strcmp(((Student const *)n1)->Prijmeni, ((Student const *)n2)->Prijmeni);
  if (tmp != 0) return tmp;
  tmp = strcmp(((Student const *)n1)->Jmeno, ((Student const *)n2)->Jmeno);
  if (tmp != 0) return tmp;
  return porovnejZnamky(((Student const *)n1)->znamka, ((Student const *)n2)->znamka);
};

Student *poleStudentu;

int main(int argc, char **argv)
{  

  char soubor[256];
  int p = 255;

  if (argc>1) {
    vstup = fopen(argv[1], "r");
    if (vstup == NULL) {
      printf("\nVstupni soubor nelze otevrit\n");
      return 1;
    }
    printf("otevren soubor %s\n", argv[1]);
  } else {
    printf("\nZadejte nazev vstupniho souboru: ");
    gets(soubor);
    vstup = fopen(soubor, "r");
    if (vstup == NULL) {
      printf("\nVstupni soubor nelze otevrit\n");
      return 1;
    }
    printf("otevren soubor %s\n", soubor);
  }

  poleStudentu = (Student *) malloc(1 * sizeof(Student));
  if(poleStudentu == NULL) {
    printf("Nedostatek pameti!\n");
    getchar();
    exit(1);
  }

  int pocetPrvku = 0;

  for (; pocetPrvku < p; ++pocetPrvku) {
    printf("pocet prvku: %d\n", pocetPrvku);
    if ((pocetPrvku % 10) == 0) {
      printf("realloc na %d\n", pocetPrvku+10);
      poleStudentu = (Student*)realloc(poleStudentu, (pocetPrvku+10) * sizeof(Student));
    }
    if (poleStudentu == NULL) {
      printf("Nedostatek pameti!\n");
      //getchar();
      exit(1);
    }
    int res = fscanf(
                vstup,
                "%s %s %f",
                poleStudentu[pocetPrvku].Jmeno,
                poleStudentu[pocetPrvku].Prijmeni,
                &poleStudentu[pocetPrvku].znamka
              );
    if (res != 3) {
      break;
    }
  }
  fclose(vstup);

  qsort(poleStudentu, pocetPrvku, sizeof(Student), &porovnejStudenty);
  
  printf("Serazeni studenti: \n");
  for (int i = 0; i < pocetPrvku; i++) {
    printf("%s %s %0.2f\n", poleStudentu[i].Jmeno, poleStudentu[i].Prijmeni, poleStudentu[i].znamka);
  }

  free(poleStudentu);
  //getchar();
  return 0;
}
Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Horracio
~ Anonymní uživatel
3 příspěvky
7. 4. 2016   #7
-
0
-

#6 KIIV

Mnohokrát děkuji, vše funguje jak má. Nyní už vidím i ty absurdní chyby, které jsem udělal (např: úplné vynechání fclose a spoustu dalších věcí).

Jsem pouze samouk začátečník, každopádně děkuji za lekci.

Nahlásit jako SPAM
IP: 77.92.207.–
KIIV
~ Moderátor
+43
God of flame
7. 4. 2016   #8
-
0
-

#7 Horracio
zapomenute fclose vadi hlavne pri zapisovani. Nektery data zustavaji v bufferu a ten se bez fclose neulozi na disk. Jinak by to byl problem u neceho, co otevira soubory dokola, nejaka sluzba ci tak.

Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 6 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý