jesper said:
Hello,
I have to load strings from a datbase and put them into an array.
I get them by packets of 100 strings of 50 characters.
Then I should do something like that : StringArray[x*100][50]
But x can be huge, then I must allocate it dynamically.
As I understand, your input,ie. packets, is firm at 100 strings of
50 characters. But the number of packets is unknown.
Then one possiblity may be to declare a StringArray
typedef char StringArray[100][50];
And make a data struct like
struct PACKET
{
StringArray *packet;
unsigned packet_nr;
}
Define a function that will allocate an array of packet
growing with you needs. See function AddPACKET below.
You will need a function that copies the packet into
the allocated space. In a example below I use the function
GetPacket. And as a test this function reads a text file stream
and stores the data in the newly allocated packet element.
Of course, you would have to adapt that function to your steam
requirements.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NR_STR 100
#define SZ_STR 50
typedef char StringArray[NR_STR][SZ_STR];
typedef enum PERR {NO_ERROR, ALLOC_FAILURE, STREAM_ERROR}PERR;
PERR packeterror;
typedef struct PACKET
{
StringArray *packet;
unsigned nr_packets;
} PACKET;
/* Prototypes */
int GetPacket(StringArray p, FILE *stream);
StringArray *AddPACKET(PACKET *p, FILE *stream);
void PrintStringArray(StringArray p, FILE *ostream);
void FreePACKET(PACKET *p);
int main(void)
{
FILE *fp;
PACKET mypackets= {NULL};
StringArray *pac;
if((fp = fopen("test.c","r")) != NULL)
{
if((pac=AddPACKET(&mypackets,fp)) != NULL)
PrintStringArray(*pac,stdout);
else switch(packeterror)
{
case ALLOC_FAILURE: puts("Allocation failure");
break;
case STREAM_ERROR: puts("Stream error");
break;
case NO_ERROR: puts("Unspecified ERROR");
};
fclose(fp);
FreePACKET(&mypackets);
}
else puts("Unable to open stream");
return 0;
}
void FreePACKET(PACKET *p)
{
free(p->packet);
p->packet = NULL;
p->nr_packets = 0U;
return;
}
StringArray *AddPACKET(PACKET *p, FILE *stream)
{
StringArray *tmp;
packeterror = NO_ERROR;
tmp = realloc(p->packet,(p->nr_packets+1)*sizeof *tmp);
if(tmp == NULL)
{
packeterror = ALLOC_FAILURE;
return NULL;
}
p->packet = tmp;
if(!GetPacket(p->packet[p->nr_packets], stream))
return NULL;
return &p->packet[p->nr_packets++];
}
void PrintStringArray(StringArray p, FILE *ostream)
{
unsigned i;
for(i = 0; i < NR_STR; i++)
printf("%s",p
);
putchar('\n');
return;
}
int GetPacket(StringArray p, FILE *stream)
{
unsigned i;
packeterror = NO_ERROR;
for(i = 0;i < NR_STR; i++)
if(!fgets(p,SZ_STR,stream))
{
packeterror = STREAM_ERROR;
return 0;
}
return 1;
}