Jak zwrócić wskaźnik na tablicę dynamiczną z funkcji

0

Witam
PROSZĘ o pomoc, już mi głowa wysiada. Muszę zwrócić wskaźnik do tablicy utworzonej w funkcji "usuwanie", a następnie w mainie skopiować jej zawartość do nowego pliku. To, co zakomentowane, nie działa. Wywala mi program kiedy dojdzie do *w - usuwanie(...). Jeden warning: warning C4700: uninitialized local variable 'w' used. Kiedy tworzę nowy plik z zawartością tab1 w funkcji, wszystko gra.

Oto kod:

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

struct student{
        int nr_ID;
        char nazwisko[20];
        char imie[20];
        double punkty;
};

student usuwanie(int n, struct student *p){
	struct student *tab1;
	int id;
	int i,stan=0;
	printf("n=%d",n);
	tab1=( struct student *) malloc ((n-1)* sizeof(struct student));

	while(stan == 0){
	printf("\nPodaj ID ktore ma byc usuniete:\n");
	scanf("%d", &id);
	
	for(i=0;i<n;i++){
		while(id == p[i].nr_ID){
			printf("ID poprawne\n");
			stan = 1;
            break;
		}
	}
	while(getchar()!='\n');
	}
	
	for(int j=0, i=0;i<n;i++){
		if(id == p[i].nr_ID){
			continue;
		}else{
			tab1[j]=p[i];
			j++;
		}
	}
	for(i=0;i<n-1;i++){
		printf("%d %s %s %d\n", tab1[i].nr_ID, tab1[i].imie, tab1[i].nazwisko, tab1[i].punkty);
	}
	FILE *stream1;
	 char nazwapliku2[20];
			  
	 printf("Podaj nazwe pliku do zapisu. (Dodaj rozszerzenie):\n");
            
			   scanf("%s", nazwapliku2);
     
            if ((stream1 = fopen (nazwapliku2, "w"))==NULL)
            {
                    printf ("\nNie mozna otworzyc pliku do zapisu.\n");
                    exit(1);
            }
     
            for (i=0; i<n-1; i++) {
				fprintf (stream1, "%d %s %s %d\n", tab1[i].nr_ID, tab1[i].imie, tab1[i].nazwisko, tab1[i].punkty);
            }
				printf("Pomyslnie zapisano.\n");            
    fclose(stream1);
	free(tab1);
	return *tab1; 
};

int wiersze(FILE *plik){
 
        int wiersz=0;
        char znak;
 
        while((znak = getc(plik)) != EOF) {
                if(znak == '\n')
                        ++wiersz;
        }  
   return wiersz;
}
 

int main(){
		
    //    student *w;
        struct student *tab;
        char plik[10];
        int i=0,n=0;
                FILE *stream;


        printf("Podaj nazwe pliku, ktory chcesz otworzyc:\n");
        scanf("%s",plik);
        strcat(plik, ".txt");
 
stream=fopen(plik,"r");
 
 
if(stream==NULL){
        printf("Blad przy otwieraniu pliku. Koniec programu\n");
		return 1;
}else{
        printf("Wczytano plik\n");
}
n = wiersze(stream);
n=n+1;
printf("n=%d", n);

rewind(stream);

tab = (struct student *)malloc(n*sizeof(struct student));
 if (fgetc(stream) == EOF)
		{
			printf("\nPlik jest pusty!\nKoniec programu\n");
			fclose(stream);
			system("pause");
			return 0;
		}
		else
		{
			rewind(stream); //jesli plik nie jest pusty, przewijamy kursor na poczatek pliku
		}
 printf("\n\nZawartosc pliku:\n\n", plik);

		 while (!feof(stream)){
			
	 fscanf( stream,"%d%s%s%d", &tab[i].nr_ID, &tab[i].imie, &tab[i].nazwisko, &tab[i].punkty);
	  printf("%d %s %s %d\n", tab[i].nr_ID, tab[i].imie, tab[i].nazwisko, tab[i].punkty);
		 i++;
 }
	printf("Zawartosc tab\n");
    for(i=0;i<n;i++){
	 printf("%d %s %s %d\n", tab[i].nr_ID, tab[i].imie, tab[i].nazwisko, tab[i].punkty);
	}

    usuwanie(n,tab);
	
	/*FILE *stream1;
	 char nazwapliku2[20];
			  
	 printf("Podaj nazwe pliku do zapisu. (Dodaj rozszerzenie):\n");
            
			   scanf("%s", nazwapliku2);
     
            if ((stream1 = fopen (nazwapliku2, "w"))==NULL)
            {
                    printf ("\nNie mozna otworzyc pliku do zapisu.\n");
                    exit(1);
            }
     
            for (i=0; i<n; i++) {
				fprintf (stream1, "%d %s %s %d\n", w[i].nr_ID, w[i].imie, w[i].nazwisko, w[i].punkty);
            }
				printf("Pomyslnie zapisano.\n");            
    fclose(stream1);
			  
	*/
                fclose( stream );
               free(tab);
			  
	
        return 0;
}


0
student *usuwanie(...){ ... }
0
spartanPAGE napisał(a):
student *usuwanie(...){ ... }

a mógłbyś napisać mi jeszcze co dać w return i jak wywołać funkcję w bloku main? Dzięki za podpowiedź, ale mam jeszcze 2 podobne programy do zrobienia na jutro, a czasu tyle co nic...

Po dodaniu samej tej *usuwanie, w return wstawiłem tab1, odkomentowałem kod z maina i zakomentowałem ten w funkcji:
nie wyrzuca mi błędu, ale w pliku zapisuj śmieci typu: 4096 ÝÝÝ!gÝqÜ ţ˙˙˙ -572662307

0

punkty masz jako double, a w funkcji fprintf dajesz informacje, że jest to integer.

0
kaczus napisał(a):

punkty masz jako double, a w funkcji fprintf dajesz informacje, że jest to integer.

już poprawiłem to.

2
  1. Wcięcia. Popraw je, możesz korzystać z http://format.krzaq.cc
  2. Sensowne nazwy zmiennych - czas poświęcony na to zwróci się z nawiązką.

Ogólnie nie wiem jaki masz problem bo trochę zagmatwane, ale:

free(tab1);
return *tab1; 

nie trzeba się wczytać w kod, żeby widzieć, że to sensu nie ma.

Miałeś zwrócić wskaźnik, a nie to co jest pod wskaźnikiem (przy okazji wprowadzając wyciek pamięci), więc prędzej

return tab1;   // oczywiscie bez free()

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