Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Array of strings

Reply
Thread Tools

Array of strings

 
 
jesper
Guest
Posts: n/a
 
      05-13-2005
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.

I have searched on Google, but I only found different solutions (malloc,
realloc, calloc, ...)
What could be the best solution ?

Thanks in advance.


 
Reply With Quote
 
 
 
 
Achintya
Guest
Posts: n/a
 
      05-13-2005
Hi,

Hoping that you can use STLs in your set-up...one solution can be....

list<vector<string> >

string to store the 50 character string
vector<> to store 100 such strings and
list<> to store the packets...

Hope you the know the usage of STLs....

If you use STL you can be least bothered about the memory allocation
and deallocation.

-vs_p...

 
Reply With Quote
 
 
 
 
Jens.Toerring@physik.fu-berlin.de
Guest
Posts: n/a
 
      05-13-2005
jesper <(E-Mail Removed)> wrote:
> 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.


Rather likely, especially if you don't know in advance how many
strings you're going to get, which wouldn't be unusal when dealing
with databases.

> I have searched on Google, but I only found different solutions (malloc,
> realloc, calloc, ...)
> What could be the best solution ?


They are not mutually exclussive and you don't mention free()
You are probably going to need malloc() and realloc() and free()
afterwards to get rid of the memory once you don't need it any-
more (calloc() probably won't be too useful here). What would be
the best solution depends a lot on your requirements, so it's a
bit like asking "Which is the best car?". What exactly do you
have problems with and how far did you got? It's usually a lot
easier to discuss things when one has some code to start with.
Or are you complete lost? And do you understand how pointers
work? If not you probably should start learning about them (plus
the methods for memory allocation) using some simpler examples
than the task you're talking about.

Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de
\__________________________ http://www.toerring.de
 
Reply With Quote
 
Jens.Toerring@physik.fu-berlin.de
Guest
Posts: n/a
 
      05-13-2005
Achintya <(E-Mail Removed)> wrote:
> Hoping that you can use STLs in your set-up...one solution can be....
> list<vector<string> >


Not very likely when the OP is asking in comp.lang.c, isn't it?

Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)-berlin.de
\__________________________ http://www.toerring.de
 
Reply With Quote
 
Targeur fou
Guest
Posts: n/a
 
      05-13-2005

jesper a écrit :
> Hello,


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]


Assuming that you have only a packet (x=1), I don't think that it would
be the correct (easiest) form to deal with 100 strings of 50
characters.
char StringArray[50][100] would be better. In that way, your strings
are "organized by lines" (X myArray[COLUMN][ROW], and when you want
to access to the i-th string, you just have to write StringArray[i].

A basic and first possible approach is to define a packet type and then
use pointers to packet typed variables.

exple:
typedef char StringsPacket[50][100];
StringsPacket * packets;

But this is ugly and difficult to handle. Furthermore It hides the
array type of StringsPacket.

A better way to do it is to use structures to split your data in simple
items.

exple:
/**
* @def LG_MAX
* Max length of a string, including the '\0'
*/
#define LG_MAX 50

/**
* @def NB_STR_PACKET
* Number of strings per packet
*/
#define NB_STR_PACKET 100

/**
* @struct typeString_s
* Structure type used for a string
*/
typedef struct typeString_s {
char str[LG_MAX]; /* String */
unsigned pos; /* Position in the packet (subscript)*/
}String_s;

/**
* @struct typeStringPacket_s
* Structure type that describes a packet of strings
*/
typedef struct typeStringPacket_s {
String_s str_arr[NB_STR_PACKET]; /* Array of String_s */
}StringPacket_s;

/**
* @struct typeNodePacket_s
*/
typedef struct typeNodePacket_s {
StringPacket_s packet; /* Packet */
struct typePacket_s * next; /* Next packet in the list */
}NodePacket_s;

In that way, it is easy to handle a linked list of NodePacket_s. This
is a common used solution when you don't know the number of data items
to handle. Here, you'll just have to allocate (and free) NodePackets_s*
variables as needed with malloc(or calloc)/free. realloc() isn't really
useful here.

HTH
Regis

 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      05-13-2005
Achintya wrote:
>
> Hoping that you can use STLs in your set-up...one solution can be....
>
> list<vector<string> >


C++ is off-topic in c.l.c. We deal with the C language.

--
Chuck F ((E-Mail Removed)) ((E-Mail Removed))
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

 
Reply With Quote
 
Al Bowers
Guest
Posts: n/a
 
      05-13-2005


jesper wrote:
> 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[i]);
putchar('\n');
return;
}

int GetPacket(StringArray p, FILE *stream)
{
unsigned i;

packeterror = NO_ERROR;
for(i = 0;i < NR_STR; i++)
if(!fgets(p[i],SZ_STR,stream))
{
packeterror = STREAM_ERROR;
return 0;
}
return 1;
}

--
Al Bowers
Tampa, Fl USA
mailto: http://www.velocityreviews.com/forums/(E-Mail Removed) (remove the x to send email)
http://www.geocities.com/abowers822/

 
Reply With Quote
 
Targeur fou
Guest
Posts: n/a
 
      05-13-2005

Targeur fou a écrit :
> jesper a écrit :
> > Hello,

>
> 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]

>
> Assuming that you have only a packet (x=1), I don't think that it

would
> be the correct (easiest) form to deal with 100 strings of 50
> characters.
> char StringArray[50][100] would be better. In that way, your strings
> are "organized by lines" (X myArray[COLUMN][ROW], and when you want
> to access to the i-th string, you just have to write StringArray[i].


Sorry, I said bullshits just above. It's char StringArray[100][50], you
were right. 2D arrays aren't so easy to use...

My apologies.

Regis

 
Reply With Quote
 
jesper
Guest
Posts: n/a
 
      05-14-2005
"jesper" <(E-Mail Removed)> wrote in message
news:428488f1$0$23872$(E-Mail Removed)...
> 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.


Thanks for answers.
In fact my loading works, but it's the "free()" which crashes.
I absolutely need to free allocated memory, as I have many other arrays to
fill afterwards.
I did this, just for test (contiguous array) :

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

#define NBENR 100

int main(int argc, char* argv[])
{
char sBuffer[50];
int i;
int j, k;

j=0;
while (j<=1000)
{
char **sArray = (char **)malloc(NBENR * sizeof(char *));
sArray[0] = (char*)malloc(NBENR * 50 * sizeof(char));
for(k= i = j; i <= k+ NBENR; i++)
{
sArray[i] = sArray[0] + i * 50;
sprintf(sBuffer, "String[%d]\n", j);
strcpy(sArray[i], sBuffer);
printf(sArray[i]);
j++;
if (j> 1000)
break;
}
// crashes !!!
free((char*)sArray[0]);

}
return 0;
}



 
Reply With Quote
 
Targeur fou
Guest
Posts: n/a
 
      05-14-2005

jesper a écrit :

Hi,

> "jesper" <(E-Mail Removed)> wrote in message
> news:428488f1$0$23872$(E-Mail Removed)...
> > 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.

>
> Thanks for answers.
> In fact my loading works, but it's the "free()" which crashes.
> I absolutely need to free allocated memory, as I have many other

arrays to
> fill afterwards.
> I did this, just for test (contiguous array) :
>
> #include <stdlib.h>
> #include <string.h>
>
> #define NBENR 100
>
> int main(int argc, char* argv[])
> {
> char sBuffer[50];
> int i;
> int j, k;
>
> j=0;
> while (j<=1000)
> {
> char **sArray = (char **)malloc(NBENR * sizeof(char *));


Notice that you have to test the return of malloc here.

> sArray[0] = (char*)malloc(NBENR * 50 * sizeof(char));


The same here. But I wonder why you don't allocate 50 characters for
each pointer to pointer to char in the packet.

e.g:

char **sArray = malloc(NBENR * sizeof (char**));
if (sArray != NULL)
{
/* Loop to allocate memory for each string in the packet */
int i, j, brkFlag = 0;
for (i=0, j=0; i<NBENR; ++i, ++j)
{
sArray[i] = malloc(50);
/* Trace and break the loop in case of failure */
if (sArray[i] == NULL)
{
fprintf(stderr,
"Failed to allocate memory for the %d string in the
packet\n",
i+1);
brkFlag = 1;
break;
}
}

if ( brkFlag != 0)
/* Loop to free already allocated items if it failed above */
for(i=0; i<=j && brkFlag ==1; ++i)
{
free(sArray[i]);
}
free(sArray);
exit(EXIT_FAILURE);
}

/* PROCESSING HERE */

/* Loop to free already memory items */
for(i=0; i<=j; ++i)
{
free(sArray[i]);
}
/* At last, free the pointer to pointers to char */
free(sArray);

}
else
{
fprintf(stderr,
"Failed to allocate memory for the pointer to pointers to
char\n");
}

> for(k= i = j; i <= k+ NBENR; i++)
> {
> sArray[i] = sArray[0] + i * 50;
> sprintf(sBuffer, "String[%d]\n", j);
> strcpy(sArray[i], sBuffer);
> printf(sArray[i]);
> j++;
> if (j> 1000)
> break;
> }
> // crashes !!!
> free((char*)sArray[0]);


Surprising. Are you sure sArray[0] (its value) isn't modified somewhere
in your program (realloc(), a shift...) ? You retrieved a pointer value
with malloc() but it shall be the same pointer value to pass to free()
to avoid crashes.

HTH
Regis

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Strings, Strings and Damned Strings Ben C Programming 14 06-24-2006 05:09 AM
Nesting an array of strings inside a array of structures Amit Limaye C++ 4 04-10-2006 06:21 PM
Catching std::strings and c-style strings at once Kurt Krueckeberg C++ 2 11-17-2004 03:53 AM
How do copy Strings from a single dimensional array to double dimensional array Venkat C++ 4 12-05-2003 09:23 AM
Comparing strings from within strings Rick C Programming 3 10-21-2003 09:10 AM



Advertisments