dynamicly build a list of strings?

  • Thread starter David. E. Goble
  • Start date
D

David. E. Goble

Hi all;

I need to build a list of strings in one function and use the list in
another function.

ie
buildlist(char list[][], FILE **infile);
{
int i;

....
while(fgets(line, LINESIZE, *infile)!=NULL)
{
list[strlen[line])=line;

/* I assume I will need malloc here some how? */
}
....
}

main(....)
{
FILE *infile, *outfile
char list[][];

buildlist(char list[][], &infile);
....
uselist(list[][], &outfile);
....
}

But this is all I remember... As you can see I need help.
Regards David. E. Goble
http://www.pnc.com.au/~degoble
degoble[AT]pnc.com.au | dgoble[AT]pnc.com.au
Po Box 648 (9 Murray St), Kingscote, Kangaroo Island SA 5223
 
B

Barry Schwarz

Hi all;

I need to build a list of strings in one function and use the list in
another function.
snip much pseudo code that only confuses the issue

Do you know the maximum number of strings you will need to process?
Do you know the maximum length of each string? If so, you could
simply define the array
char list[MAX_NUM][MAX_LEN];
in main and pass it to both functions.

If some of these values are only known at execution time, then you
will need to malloc and friends. One common technique is to define a
char ** (call it list). Assign this pointer the address of a
dynamically allocated block capable of holding N char*. As you
process each string, allocate space for it and store the address of
that space in list. When i gets up to N, use realloc to expand the
amount of space list points to. Repeat until all strings are
processed.


<<Remove the del for email>>
 
N

Neil Kurzman

David. E. Goble said:
Hi all;

I need to build a list of strings in one function and use the list in
another function.

ie
buildlist(char list[][], FILE **infile);
{
int i;

...
while(fgets(line, LINESIZE, *infile)!=NULL)
{
list[strlen[line])=line;

/* I assume I will need malloc here some how? */
}
...
}

main(....)
{
FILE *infile, *outfile
char list[][];

buildlist(char list[][], &infile);
...
uselist(list[][], &outfile);
...
}

But this is all I remember... As you can see I need help.
Regards David. E. Goble
http://www.pnc.com.au/~degoble
degoble[AT]pnc.com.au | dgoble[AT]pnc.com.au
Po Box 648 (9 Murray St), Kingscote, Kangaroo Island SA 5223


Not list[strlen[line])=line; use strncpy()

if the number and length of the strings is known use a 2D array
If the number of messages is not known you may want to use a linked list.

If you you know the number of messages use an array of pointers.
You can then malloc them one by one as then come in (+1 for the Null)

for extra credit you can read the file, count the strings, then malloc
the array of pointers.

Since there are many ways to do this this is just my opinion.
 
J

Jonathan Burd

Not list[strlen[line])=line; use strncpy()


<snip>

I would suggest using strlcpy instead. The latest source code is
available from the OpenBSD ftp. strlcpy guarantees null termination
of the string and is more efficient since it does not pad
the string buffer with redundant NULs. strncpy can be a problem if
used improperly (you have to remember to pass the correct
count of characters and then manually terminate the string).
Also, strlcpy is more secure and more intuitive to use.
You simply pass the size of the buffer in bytes as the last
parameter.

/* xstrlcpy.c */
#include <stddef.h>

/*
@synopsis
#include <xstring.h>
size_t xstrlcpy (char *dst, const char *src, size_t siz);
@description
Copies not more than siz-1 characters into the array
pointed to by dst from the string pointed to by src
(characters that follow a null character are not copied).
If copying takes place between two objects that overlap,
the behavior is undefined.

This function does not add redundant NUL characters
to fill in the size requirements. The array pointed
to by dst is guaranteed to be terminated by a NUL
character (unless siz is zero).
@param dst pointer to the destination buffer array
@param src pointer to the source string
@param siz the size of the destination buffer array
object including the space for a terminating
NUL character.
@return
The length of the string pointed to by dst after
copying (the number of characters before the terminating
null character).

If the returned value is greater than or equal to
siz, truncation has occurred.
@remarks
This function should be used in place of the functions
xstrcpy and xstrncpy whenever possible due to the following
reasons:
* reduces the risk of a buffer overflow
* guarantees NUL-termination of the destination buffer
* is more logical since you only have to remember to
pass the size of the entire destination array object
* efficiency is much better than xstrncpy while negligibly
lesser than xstrcpy.

The xstrncpy function is useful when you do not
need to terminate the destination array with a NUL-character
and want to copy exactly the number of characters specified.
@references
* ISO/IEC 9899:1999 (C Standard) -- 7.21.2.4 -- The strncpy function
* "strlcpy and strlcat -- consistent, safe, string copy
and concatenation" - Todd C. Miller and Theo de Raadt
@source
The source code for this function was obtained from the
OpenBSD libc string routines library. It is available under a
BSD-style license.
@see
xstrncpy
xstrcpy
*/
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
xstrlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
register size_t n = siz;

/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}

/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}

return(s - src - 1); /* count does not include NUL */
}

Regards,
Jonathan.
 
J

Jonathan Burd

David. E. Goble said:
Hi all;

I need to build a list of strings in one function and use the list in
another function.

ie
buildlist(char list[][], FILE **infile);
{
int i;

...
while(fgets(line, LINESIZE, *infile)!=NULL)
{
list[strlen[line])=line;


strlen is a function. Correct this line.
Use strlcpy. See my reply elsewhere.
/* I assume I will need malloc here some how? */
}
...
}

main(....)
{
FILE *infile, *outfile
char list[][];

buildlist(char list[][], &infile);
...
uselist(list[][], &outfile);
...
}

Regards,
Jonathan.
 
B

Barry Schwarz

Hi all;

I need to build a list of strings in one function and use the list in
another function.
snip much pseudo code that only confuses the issue

Do you know the maximum number of strings you will need to process?
Do you know the maximum length of each string? If so, you could
simply define the array
char list[MAX_NUM][MAX_LEN];
in main and pass it to both functions.

If some of these values are only known at execution time, then you
will need to malloc and friends. One common technique is to define a
char ** (call it list). Assign this pointer the address of a
dynamically allocated block capable of holding N char*. As you
process each string, allocate space for it and store the address of
that space in list. When i gets up to N, use realloc to expand the
amount of space list points to. Repeat until all strings are
processed.


<<Remove the del for email>>



<<Remove the del for email>>
 
C

CBFalconer

Jonathan said:
Neil Kurzman wrote:

<snip>

I would suggest using strlcpy instead. The latest source code is
available from the OpenBSD ftp. strlcpy guarantees null termination
of the string and is more efficient since it does not pad
the string buffer with redundant NULs. strncpy can be a problem if
used improperly (you have to remember to pass the correct
count of characters and then manually terminate the string).
Also, strlcpy is more secure and more intuitive to use.
You simply pass the size of the buffer in bytes as the last
parameter.

.... snip code ...

I agree. You can also get a slightly different version at:

<http://cbfalconer.home.att.net/download/strlcpy.zip>

which accepts NULL as source (but not dest) parameter, and treats
it as an empty string. It also has (to my mind) the consistent
approach to size less than strlen(dest) in strlcat of always
returning the size required for the combined strings. The zip also
contains links to the BSD publications. My code has been put in
the public domain, so there are no restrictions whatsoever on it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top