tylko po co maciez ? czemu koniecznie kwadrat albo prostokat?
czy nie lepiej dla danych:
7 6 7
1 -2 1
3 1 -2
100
0
0
stworzyc strukture "prawie tablicowa" znczy pierwsza (zerowa) komorka trzyma dlugosc linii, a w reszczie znajduja sie dane:
3 7 6 7
3 1 -2 1
3 3 1 -2
1 100
1 0
1 0
#include <string.h>
#include <stdio.h>
int main(int argc,char** argv){
#define MAXLINESIZE 1024
int** tab=0;
int wa=0;
char s[MAXLINESIZE];
if(argc<2){
printf("uruchom program z nazwa pliku jako parametrem\n");
return -1;
}
FILE* f=fopen(argv[1],"r");
if(!f){
printf("nie mozna otworzyc pliku\n");
return -2;
}
int k,w=0; // w jak wiersz
while(fgets(s,MAXLINESIZE,f)){ // wczytac linie max 512-1 znakow z pliku
printf("linia=%s",s);
char* p=s;
if(w>=wa){
if(wa){
wa*=2;
}else wa=1;
tab=(int**)realloc(tab,wa*sizeof(int*));
if(!tab){
printf("brak pamieci!\n");
return -3;
}
}
tab[w]=(int*)malloc(sizeof(int));
if(!tab[w]){
printf("brak pamieci!\n");
return -4;
}
tab[w][0]=k=0;
while(p=strtok(p," \n\r")){
// if(*p){ // to nie nastapi, bo strtok zwroci wczesniej 0
printf("%s ",p);
char* r;
int i=(int)strtol(p,&r,10);
if(tab[w][0]>=k){
if(k){
k*=2;
}else k=1;
tab[w]=(int*)realloc(tab[w],(k+1)*sizeof(int));
if(!tab[w]){
printf("brak pamieci!\n");
return -5;
}
}
tab[w][0]++;
if(!*r){
printf("w=%d, tab[%d][0]=%d tab[%d][%d]=%d\n",w,w,tab[w][0],w,tab[w][0],i);
tab[w][tab[w][0]]=i;
}else printf("bledny znak: %c\n",*r);
// }else printf("linia pusta!\n");
p=0;
}
printf("k=%d, tab[%d][0]=%d => ",k,w,tab[w][0]);
if(k>tab[w][0]){
k=tab[w][0];
tab[w]=(int*)realloc(tab[w],(k+1)*sizeof(int));
}
printf("k=%d, tab[%d][0]=%d\n",k,w,tab[w][0]);
w++;
}
fclose(f);
printf("wa=%d w=%d\n",wa,w);
if(wa>w)tab=(int**)realloc(tab,(wa=w)*sizeof(int*));
printf("wa=%d w=%d\n\n========================\n\n",wa,w);
w=0;
while(w<wa){
k=0;
printf("%02d %d => ",w+1,tab[w][0]);
while(k<tab[w][0])printf("%d ",tab[w][++k]);
printf("\n");
w++;
}
while(wa--)free(tab[wa]);
free(tab);
return 0;
}
i alokowac wszystko dynamicznie ? masz zmienna 'wa' w ktorej trzymasz ilosc zaalokowanych wierszy. powiedzmy wartosc poczatkowa 0, wczytujesz w-ta linijke, sprawdzasz czy jest zaalokowana przestrzen na ta linie. jesli w>=wa (wlasciwie to w nigdy nie bedzie wieksze od wa, ale taki warunek jest bezpieczniejszy) to musisz zaalokowac nowa przestrzen, teraz rozmiar przestrzeni alokowanej zalezy od wa. jesli wa==0, to ustawiasz wa=1 i alokujesz jedna linijke, w inym wypadku alokujesz 2x wiecej niz bylo poprzednio (wa*=2), w ten sposob:
- nigdy nie zejdziesz ponizej 50% wypelnienia tablicy.
- skoro doszedles do takiej a nie innej liczby linii to prawdopodobienstwo ze w pliku jest drugie tyle linii jest duzo wieksze niz ze bedzie tylko jedna.
dlatego szkoda czasu procesora i zasobow, nie realokuje sie pamieci "o jeden wiecej" tylko "2 razy wiecej"
po zakonczeniu czytania zwalniasz nadmiar zaalokowanej pamieci
podobnie z alokacja kolumn, z ta roznica, ze alokujesz o komorke wiecej, komorka o zerowym indeksie przetrzymuje informacje o ilosci zapamietanych liczb.