Wysypuje się i nie wiem dlaczego :(

0

Mam taki kod:

    if(length>0)
        while(i < length)
        {
            c = content[i];
            if(c == '\t' || c == '\n')
            {
                temp[cIndex] = '\0';
                shows[x][y] = malloc(strlen(temp));
                strcpy(shows[x][y],temp);
                free(temp);
                temp = malloc(100);
                cIndex = 0;
                if(c == '\t')
                {
                    printf("%s\t",shows[x][y]);
                    x++;
                }
                if(c == '\n')
                {
                    printf("%s\n",shows[x][y]);
                    x = 0;
                    y++;
                }
            }
            else
                temp[cIndex++] = c;
            i++;
        }
    free(temp); // dodatkowo zwolnic shows
    free(content);

Zawartość zmiennej contents:

ARS. Aneks Ambassada (2013) 2013-11-03 22.10
ARS. Aneks Ambassada (2013) 2013-11-04 22.10
ARS. Aneks Ambassada (2013) 2013-11-05 22.10
ARS. Aneks Ambassada (2013) 2013-10-30 20.15
ARS. Aneks Ambassada (2013) 2013-10-31 20.15
ARS. Aneks Ambassada (2013) 2013-11-01 22.10
ARS. Aneks Ambassada (2013) 2013-11-02 22.10
ARS. Aneks Chce się żyć (2013) 2013-11-03 20.15
ARS. Aneks Chce się żyć (2013) 2013-11-04 12.00
ARS. Aneks Chce się żyć (2013) 2013-11-04 20.15
ARS. Aneks Chce się żyć (2013) 2013-11-05 20.15
ARS. Aneks Chce się żyć (2013) 2013-10-30 12.30

W powyższym są 4 kolumny oddzielone tabulatorem co może nie być widać.

Po uruchomieniu widać:

ARS. Aneks Ambassada (2013)

po czym się wysypuje.
W trybie debugowania przechodzi.

Czy ma ktoś pomysł co robię źle? :(

3

erm, nie alokujesz pamięci na '\0'?

0

A tak, wystarczyło zamienić

shows[x][y] = malloc(strlen(temp));

na

shows[x][y] = malloc(strlen(temp)+1);

Tragedia, że taki drobiazg potrafi rozwalić cały program...

1

Wysypuje się bo mażesz po pamięci, powinno być: malloc(strlen(temp)+1);
Całość proponuję zrobić po ludzku:

int y=0,x,ok=1;
char *s,*end,*next;
for(s=content,end=s+length,next=0;s<end;s=next+1)
  {
   for(x=0;x<4;++x)
     {
      next=strchr(s,x<3?'\t':'\n');
      if(!next) exit(1); // nie powinno tu wchodzić chyba że plik nie poprawny
      *next=0;
      shows[x][y]=s; // powinieneś stosować shows[y][x]
     }
   ++y;
  }
...
free(content); // to zrobisz dopiero jak już nie potrzebujesz tablicy shows zaś wszystkich shows[x][y] nie musisz zwalniać.

Ba podejrzewam że ten content wczytałeś z pliku, jeżeli tak to trzeba to jeszcze prościej zrobić.

0

Sprytnie to zrobiłeś ;) Widać, że masz dużą praktykę.

Jest wczytane z pliku. Jakaś wskazówka co zrobić prościej?

1
int y,x;
FILE *fd;
fd=fopen("plik.txt","r+");
char buf[4][100];
for(y=0;fscanf(fd,"%99s %99s %99s %99s",buf[0],buf[1],buf[2],buf[3])==4;++y) for(x=0;x<4;++x) shows[x][y]=strdup(buf[x]); // powinieneś stosować shows[y][x]
fclose(fd);

//Pisane z palca mogłem gdzieś się kropnąć

1

Było pytanie z sortowaniem ale zniknęło zanim wpisałem odpowiedź:

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

int cmpcol(const char **a,const char **b,int col)
  {
   return strcmp(a[col],b[col]);
  }

int cmp1(const void *a,const void *b)
  {
   return cmpcol((const char **)a,(const char **)b,0);
  }

int cmp2(const void *a,const void *b)
  {
   return cmpcol((const char **)a,(const char **)b,1);
  }

int cmp3(const void *a,const void *b)
  {
   return cmpcol((const char **)a,(const char **)b,2);
  }

int cmp4(const void *a,const void *b)
  {
   return cmpcol((const char **)a,(const char **)b,3);
  }

void srt(char *shows[][4],unsigned Y,int (*cmpfun)(const void *,const void *))
  {
   qsort(shows,Y,4*sizeof(char*),cmpfun);
  }
  
void prn(char *shows[][4],unsigned Y)
  {
   int y,x;
   for(y=0;y<Y;++y,printf("\n")) for(x=0;x<4;++x) printf("%2s",shows[y][x]);
   printf("\n");
  }

int main()
  {
   char *shows[][4]={{"D","2","3","1"},{"C","1","2","4"},{"B","4","4","2"},{"A","3","1","3"}};
   prn(shows,4);
   srt(shows,4,cmp1);
   prn(shows,4);
   srt(shows,4,cmp2);
   prn(shows,4);
   srt(shows,4,cmp3);
   prn(shows,4);
   srt(shows,4,cmp4);
   prn(shows,4);
   return 0;
  }
0

Usunąłem wpis, bo zorientowałem się, że bzdury napisałem.

Da się qsort wykorzystać do sortowania tablic po wskazanej kolumnie? Szukałem i we wszystkich przykładach sortował po pierwszej.

Ps. Zamieszczam działającą funkcję z bąbelkami.

void sortShows(char *shows[4][5000], int by, int count)
{
    int j;
    int k1, k2, k3;
    if(by==0) k1=1,k2=2,k3=3;
    if(by==1) k1=0,k2=2,k3=3;
    if(by==2) k1=0,k2=1,k3=3;
    if(by==3) k1=0,k2=1,k3=2;
    char *temp;
    do
    {
        for(j=0; j<count-1; j++)
        {
            if(strcmp(shows[by][j],shows[by][j+1])>0)
            {
                temp = shows[by][j];
                shows[by][j] = shows[by][j+1];
                shows[by][j+1] = temp;

                temp = shows[k1][j];
                shows[k1][j] = shows[k1][j+1];
                shows[k1][j+1] = temp;

                temp = shows[k2][j];
                shows[k2][j] = shows[k2][j+1];
                shows[k2][j+1] = temp;

                temp = shows[k3][j];
                shows[k3][j] = shows[k3][j+1];
                shows[k3][j+1] = temp;

            }
        }
        count--;
    }
    while(count>0);
}
0

Grrrr, może czasami się zastanów jak widzisz powtarzające się fragmenty kodu.

void sortShows(char *shows[4][5000], int by, int count)
{
    int j,k;
    char *temp;
    for(;count>1;--count)
    {
        for(j=1;j<count;++j)
        {
            if(strcmp(shows[by][j-1],shows[by][j])>0)
            {
                for(k=0;k<4;++k)
                {
                    temp = shows[k][j-1];
                    shows[k][j-1] = shows[k][j];
                    shows[k][j] = temp;
                }
            }
        }
    }
}

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