473,327 Members | 2,055 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

Dynamic Arrays

Hi Everyone,

I apologise if this is covered in the FAQ, I did look, but nothing
actually stood out to me as being relative to my subject.

I want to create a 2 dimensional array, a 'array of strings'. I already
know that no individual string will be longer than 50 characters. I just
don't know before run time how many elements of the array will be needed.

I have heard it is possible to dynamically allocate memory for a 2
dimensional array as long as the size of the 2nd element is shown. Is
this correct? And if so could someone post a simple example for me, to
base my own code off.

Thanks

--
------
Materialised

perl -e 'printf "%silto%c%sck%ccodegurus%corg%c", "ma", 58, "mi", 64,
46, 10;'
Nov 14 '05 #1
6 2944
"Materialised" <Ma**********@privacy.net> wrote in message
news:c6************@ID-220437.news.uni-berlin.de...
I want to create a 2 dimensional array, a 'array of strings'. I already
know that no individual string will be longer than 50 characters. I just
don't know before run time how many elements of the array will be needed.

I have heard it is possible to dynamically allocate memory for a 2
dimensional array as long as the size of the 2nd element is shown. Is
this correct? And if so could someone post a simple example for me, to
base my own code off.


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

int main()
{
char (*arr)[50] = malloc(10 * sizeof *arr);
if (arr)
{
int i;
for (i = 0; i < 10; i++)
{
sprintf(arr[i] "%d", i);
puts(arr[i]);
}
free(arr);
}
}
Nov 14 '05 #2

"Materialised" <Ma**********@privacy.net> wrote in message
news:c6************@ID-220437.news.uni-berlin.de...
Hi Everyone,

I apologise if this is covered in the FAQ, I did look, but nothing
actually stood out to me as being relative to my subject.

I want to create a 2 dimensional array, a 'array of strings'. I already
know that no individual string will be longer than 50 characters. I just
don't know before run time how many elements of the array will be needed.

I have heard it is possible to dynamically allocate memory for a 2
dimensional array as long as the size of the 2nd element is shown. Is
this correct? And if so could someone post a simple example for me, to
base my own code off.


There are several published. I did a googles search in googles for
"array of strings" and came up with several examples. Here is one
posted about one year ago in comp.lang.c

C code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct NAME{
char **name;
size_t count;
}NAME;

char *addNAME(NAME *p,const char *name);
void freeNAME(NAME *p);

int main(void)
{
NAME president = {0}; /* initalized zero neccessary for start*/
size_t i;

addNAME(&president,"George Washington");
addNAME(&president,"Abe Lincoln");
puts("Presidents in the array are");
for(i = 0; i < president.count;i++)
printf("\t%s\n",president.name[i]);
freeNAME(&president);
printf("\nAfter freeing the array\n"
"There are %u names in the array\n",president.count);
return 0;
}

char *addNAME(NAME *p, const char *name)
{
char **tmp;
size_t i;

if(!p || !name) return NULL;
i = p->count;
if((tmp = realloc(p->name,(i+1)*sizeof(*p->name))) == NULL)
return NULL;
if((tmp[i] = malloc(strlen(name)+1)) == NULL)
return NULL;
strcpy(tmp[i],name);
p->count++;
p->name = tmp;
return p->name[i];
}

void freeNAME(NAME *p)
{
size_t i;

if(!p) return;
for(i = 0;i < p->count;i++)
free(p->name[i]);
free(p->name);
p->name = NULL;
p->count = 0;
}

Thapani.
Nov 14 '05 #3
In <c6************@ID-220437.news.uni-berlin.de> Materialised <Ma**********@privacy.net> writes:
I apologise if this is covered in the FAQ, I did look, but nothing
actually stood out to me as being relative to my subject.

I want to create a 2 dimensional array, a 'array of strings'. I already
know that no individual string will be longer than 50 characters. I just
don't know before run time how many elements of the array will be needed.

I have heard it is possible to dynamically allocate memory for a 2
dimensional array as long as the size of the 2nd element is shown. Is
this correct?
Yes, you can use a pointer to arrays of that size.
And if so could someone post a simple example for me, to
base my own code off.


You can find the cryptical syntax for declaring a pointer to array in
the FAQ. I'll show the readable approach.

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

#define SIZE (50 + 1)
typedef char array_t[SIZE];

int main(int argc, char **argv)
{
array_t *p;
int i;

if (argc == 0) return 0;
p = calloc(argc, sizeof *p); /* or sizeof(array_t) */
if (p == NULL) return EXIT_FAILURE;
for (i = 0; i < argc; i++) strncpy(p[i], argv[i], SIZE - 1);
/* ... */
return 0;
}

If you no longer need the 2-dimensional array at some point in your
program, you can free it with a plain free(p) call. And you can access
individual characters in the array using the p[i][j] syntax (*before*
calling free).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #4
Dan Pop wrote:
In <c6************@ID-220437.news.uni-berlin.de> Materialised <Ma**********@privacy.net> writes:

I apologise if this is covered in the FAQ, I did look, but nothing
actually stood out to me as being relative to my subject.

I want to create a 2 dimensional array, a 'array of strings'. I already
know that no individual string will be longer than 50 characters. I just
don't know before run time how many elements of the array will be needed.

I have heard it is possible to dynamically allocate memory for a 2
dimensional array as long as the size of the 2nd element is shown. Is
this correct?

Yes, you can use a pointer to arrays of that size.

And if so could someone post a simple example for me, to
base my own code off.

You can find the cryptical syntax for declaring a pointer to array in
the FAQ. I'll show the readable approach.

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

#define SIZE (50 + 1)
typedef char array_t[SIZE];

int main(int argc, char **argv)
{
array_t *p;
int i;

if (argc == 0) return 0;
p = calloc(argc, sizeof *p); /* or sizeof(array_t) */
if (p == NULL) return EXIT_FAILURE;
for (i = 0; i < argc; i++) strncpy(p[i], argv[i], SIZE - 1);
/* ... */
return 0;
}

If you no longer need the 2-dimensional array at some point in your
program, you can free it with a plain free(p) call. And you can access
individual characters in the array using the p[i][j] syntax (*before*
calling free).

Dan

Thanks dan that clarified it for me, and thanks to the other posters as
well.

--
------
Materialised

perl -e 'printf "%silto%c%sck%ccodegurus%corg%c", "ma", 58, "mi", 64,
46, 10;'
Nov 14 '05 #5


Materialised wrote:
Hi Everyone,

I apologise if this is covered in the FAQ, I did look, but nothing
actually stood out to me as being relative to my subject.

I want to create a 2 dimensional array, a 'array of strings'. I already
know that no individual string will be longer than 50 characters. I just
don't know before run time how many elements of the array will be needed.

I have heard it is possible to dynamically allocate memory for a 2
dimensional array as long as the size of the 2nd element is shown.

Size of the second dimension , that is . (instead of 2nd element).
Because in C , even a 2-D array is actually implemented as a single-dim.
array and so it needs the II dimension to locate an element.
--
Rakesh Kumar
** Remove nospamplz from my email address for my real email **
Nov 14 '05 #6
Materialised <Ma**********@privacy.net> wrote in message news:<c6************@ID-220437.news.uni-berlin.de>...
Hi Everyone,

I apologise if this is covered in the FAQ, I did look, but nothing
actually stood out to me as being relative to my subject.

I want to create a 2 dimensional array, a 'array of strings'. I already
know that no individual string will be longer than 50 characters. I just
don't know before run time how many elements of the array will be needed.

I have heard it is possible to dynamically allocate memory for a 2
dimensional array as long as the size of the 2nd element is shown. Is
this correct? And if so could someone post a simple example for me, to
base my own code off.

Thanks


If you want to borrow free dynamic-array-of-string code, look at
FreeDOS edlin, which actually uses dynamic-array-of-dynamic-string,
which is even cooler. Anyway, here's the URL:
http://www.ibiblio.org/pub/micro/pc-...ne/edlin21.zip

and the relevant code:

/* defines.h -- standard defines */

#ifndef DEFINES_H
#define DEFINES_H

#include <stddef.h>

typedef void fvoid_t ();

typedef enum capacity
{
default_size,
reserve
} capacity;

#ifndef NPOS
#define NPOS ((size_t)(-1))
#endif

void Nomemory ();

#endif

/* END OF FILE */

/* defines.c -- implementation of functions from defines.h

AUTHOR: Gregory Pietsch

*/

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

void
Nomemory (void)
{
fputs ("No memory\n", stderr);
abort ();
}

/* END OF FILE */

/* dynarray.h - dynamic array header

*/

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

#define _VAL(y,x) y ## x
#define _NM(y,x) _VAL(y,x)

#ifdef PROTOS_ONLY

/* types */

typedef struct _NM (TS, _ARRAY_T)
{
T *_Ptr;
size_t _Len, _Res;
} _NM (TS, _ARRAY_T);

_NM (TS, _ARRAY_T) * _NM (TS, _create) (void);
void
_NM (TS, _destroy) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _ctor) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _ctor_with_size) (_NM (TS, _ARRAY_T) *, size_t,
capacity);
void
_NM (TS, _copy_ctor) (_NM (TS, _ARRAY_T) *, _NM (TS, _ARRAY_T)
*);
void
_NM (TS, _ctor_from_ptr) (_NM (TS, _ARRAY_T) *, T *, size_t);
void
_NM (TS, _dtor) (_NM (TS, _ARRAY_T) *);
_NM (TS, _ARRAY_T) * _NM (TS, _append) (_NM (TS, _ARRAY_T) *, T *,
size_t,
size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _assign) (_NM (TS, _ARRAY_T) *, T *,
size_t,
size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _insert) (_NM (TS, _ARRAY_T) *, size_t,
T *,
size_t, size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _remove) (_NM (TS, _ARRAY_T) *, size_t,
size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _subarray) (_NM (TS, _ARRAY_T) *,
_NM (TS, _ARRAY_T) *,
size_t,
size_t);
void
_NM (TS, _swap) (_NM (TS, _ARRAY_T) *, _NM (TS, _ARRAY_T) *);
T *
_NM (TS, _get_at) (_NM (TS, _ARRAY_T) *, size_t);
void
_NM (TS, _put_at) (_NM (TS, _ARRAY_T) *, size_t, T *);
T *
_NM (TS, _base) (_NM (TS, _ARRAY_T) *);
size_t
_NM (TS, _length) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _resize) (_NM (TS, _ARRAY_T) *, size_t, T *);
size_t
_NM (TS, _reserve) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _set_reserve) (_NM (TS, _ARRAY_T) *, size_t);

#else

#ifndef Tctor
#define Tctor(x)
#endif
#ifndef Tdtor
#define Tdtor(x)
#endif
#ifndef Tassign
#define Tassign(x,y) (*(x) = *(y))
#endif

/* functions */

static void _NM (TS, _Xinv) (void)
{
fputs ("Invalid dynamic array argument\n", stderr);
abort ();
}

static void _NM (TS, _Xlen) (void)
{
fputs ("Length error: dynamic array too long\n", stderr);
abort ();
}

static void _NM (TS, _Xran) (void)
{
fputs ("Out of range: invalid dynamic array position\n", stderr);
abort ();
}

static void _NM (TS, _Tidy) (_NM (TS, _ARRAY_T) * this, int
_Constructed)
{
size_t i;

if (_Constructed && this->_Ptr != 0)
{
for (i = 0; i < this->_Len; i++)
Tdtor (this->_Ptr + i);
free (this->_Ptr);
}
this->_Len = 0;
this->_Ptr = 0;
this->_Res = 0;
}

static void _NM (TS, _Grow) (_NM (TS, _ARRAY_T) * this, size_t _N, T *
_S,
int _Trim)
{
size_t _Os = this->_Ptr == 0 ? 0 : this->_Res;
size_t _I, _M, _R;
T *_Np;

if (_N == 0)
{
if (_Trim)
_NM (TS, _Tidy) (this, 1);
}
else if (_N == _Os || _N < _Os && !_Trim);
else
{
_M = this->_Ptr == 0 && _N < this->_Res ? this->_Res : _N;
_Np = calloc (_M, sizeof (T));
if (_Np == 0)
Nomemory (); /* no memory */
for (_I = 0; _I < _M; _I++)
Tctor (_Np + _I);
_R = _M;
_M = _N < this->_Len ? _N : this->_Len;
for (_I = 0; _I < _M; ++_I)
Tassign (_Np + _I, this->_Ptr + _I);
if (_S != 0)
for (; _I < this->_Res; ++_I)
Tassign (_Np + _I, _S);
_NM (TS, _Tidy) (this, 1);
this->_Ptr = _Np;
this->_Res = _R;
}
this->_Len = _N;
}

_NM (TS, _ARRAY_T) * _NM (TS, _create) (void)
{
_NM (TS, _ARRAY_T) * x = malloc (sizeof (_NM (TS, _ARRAY_T)));

if (x == 0)
Nomemory ();
_NM (TS, _Tidy) (x, 0);
return x;
}

void _NM (TS, _destroy) (_NM (TS, _ARRAY_T) * x)
{
_NM (TS, _Tidy) (x, 1);
free (x);
}

void _NM (TS, _ctor) (_NM (TS, _ARRAY_T) * this)
{
_NM (TS, _Tidy) (this, 0);
}

void _NM (TS, _ctor_with_size) (_NM (TS, _ARRAY_T) * this, size_t n,
capacity c)
{
_NM (TS, _Tidy) (this, 0);
this->_Res = n;
if (c == default_size)
_NM (TS, _Grow) (this, n, 0, 0);
}

void _NM (TS, _copy_ctor) (_NM (TS, _ARRAY_T) * this, _NM (TS,
_ARRAY_T) * x)
{
size_t i;

_NM (TS, _Tidy) (this, 0);
_NM (TS, _Grow) (this, _NM (TS, _length) (x), 0, 0);
for (i = 0; i < this->_Len; i++)
Tassign (this->_Ptr + i, x->_Ptr + i);
}

void _NM (TS, _ctor_from_ptr) (_NM (TS, _ARRAY_T) * this, T * s,
size_t n)
{
if (s == 0)
_NM (TS, _Xinv) ();
_NM (TS, _Tidy) (this, 0);
_NM (TS, _assign) (this, s, n, 1);
}

void _NM (TS, _dtor) (_NM (TS, _ARRAY_T) * this)
{
_NM (TS, _Tidy) (this, 1);
}

_NM (TS, _ARRAY_T) * _NM (TS, _append) (_NM (TS, _ARRAY_T) * this, T *
_S,
size_t _N, size_t _D)
{
size_t _I;

if (NPOS - this->_Len <= _N)
_NM (TS, _Xlen) ();
_I = this->_Len;
for (_NM (TS, _Grow) (this, _N += _I, 0, 0); _I < _N; ++_I, _S +=
_D)
Tassign (this->_Ptr + _I, _S);
return this;
}

_NM (TS, _ARRAY_T) * _NM (TS, _assign) (_NM (TS, _ARRAY_T) * this, T *
_S,
size_t _N, size_t _D)
{
size_t _I;

_NM (TS, _Grow) (this, _N, 0, 1);
for (_I = 0; _I < _N; ++_I, _S += _D)
Tassign (this->_Ptr + _I, _S);
return this;
}

_NM (TS, _ARRAY_T) * _NM (TS, _insert) (_NM (TS, _ARRAY_T) * this,
size_t _P,
T * _S, size_t _N, size_t _D)
{
size_t _I;

if (this->_Len < _P)
_NM (TS, _Xran) ();
if (NPOS - this->_Len <= _N)
_NM (TS, _Xlen) ();
if (0 < _N)
{
_I = this->_Len - _P;
for (_NM (TS, _Grow) (this, _N + this->_Len, 0, 0); 0 < _I;)
{
--_I;
Tassign (this->_Ptr + (_P + _N + _I), this->_Ptr + (_P +
_I));
}
for (_I = 0; _I < _N; ++_I, _S += _D)
Tassign (this->_Ptr + (_P + _I), _S);
}
return this;
}

_NM (TS, _ARRAY_T) * _NM (TS, _remove) (_NM (TS, _ARRAY_T) * this,
size_t _P,
size_t _N)
{
size_t _M, _I;

if (this->_Len < _P)
_NM (TS, _Xran) ();
if (this->_Len - _P < _N)
_N = this->_Len - _P;
if (0 < _N)
{
_M = this->_Len - _P - _N;
for (_I = 0; _I < _M; ++_I)
Tassign (this->_Ptr + (_P + _I), this->_Ptr + (_P + _I + _N));
_NM (TS, _Grow) (this, this->_Len - _N, 0, 0);
}
return this;
}

_NM (TS, _ARRAY_T) * _NM (TS, _subarray) (_NM (TS, _ARRAY_T) * this,
_NM (TS, _ARRAY_T) * _X,
size_t _P,
size_t _N)
{
if (this->_Len < _P)
_NM (TS, _Xran) ();
if (this->_Len - _P < _N)
_N = this->_Len - _P;
return this == _X ? (_NM (TS, _remove) (this, _P + _N, NPOS),
_NM (TS, _remove) (this, 0, _P))
: _NM (TS, _assign) (_X, this->_Ptr + _P, _N, 1);
}

void _NM (TS, _swap) (_NM (TS, _ARRAY_T) * this, _NM (TS, _ARRAY_T) *
_X)
{
T *_Tp;
size_t _T;

_Tp = this->_Ptr;
this->_Ptr = _X->_Ptr;
_X->_Ptr = _Tp;
_T = this->_Len;
this->_Len = _X->_Len;
_X->_Len = _T;
_T = this->_Res;
this->_Res = _X->_Res;
_X->_Res = _T;
}

T *_NM (TS, _get_at) (_NM (TS, _ARRAY_T) * this, size_t _I)
{
if (this->_Len <= _I)
_NM (TS, _Xran) ();
return this->_Ptr + _I;
}

void _NM (TS, _put_at) (_NM (TS, _ARRAY_T) * this, size_t _I, T * _X)
{
if (this->_Len < _I)
_NM (TS, _Xran) ();
else if (this->_Len == _I)
_NM (TS, _append) (this, _X, 1, 1);
else
Tassign (this->_Ptr + _I, _X);
}

T *_NM (TS, _base) (_NM (TS, _ARRAY_T) * this)
{
return this->_Len != 0 ? this->_Ptr : 0;
}

size_t _NM (TS, _length) (_NM (TS, _ARRAY_T) * this)
{
return this->_Len;
}

void _NM (TS, _resize) (_NM (TS, _ARRAY_T) * this, size_t _N, T * _X)
{
_NM (TS, _Grow) (this, _N, _X, 1);
}

size_t _NM (TS, _reserve) (_NM (TS, _ARRAY_T) * this)
{
return this->_Res;
}

void _NM (TS, _set_reserve) (_NM (TS, _ARRAY_T) * this, size_t _R)
{
if (this->_Ptr == 0)
this->_Res = _R;
}

#endif

#undef _NM
#undef _VAL

/* END OF FILE */

/* dynamic string function header

AUTHOR: Gregory Pietsch
*/

#ifndef DYNSTR_H
#define DYNSTR_H

#include "defines.h"

typedef struct STRING_T
{
char *ptr;
size_t len, res;
} STRING_T;

/* exported functions */

void DSctor (STRING_T * this);
void DSctor_with_size (STRING_T * this, size_t n, capacity c);
void DSdtor (STRING_T * this);
STRING_T *DScreate (void);
void DSdestroy (STRING_T * this);
STRING_T *DSappendchar (STRING_T * this, int c, size_t nr);
STRING_T *DSappendcstr (STRING_T * this, char *s, size_t ns);
STRING_T *DSappend (STRING_T * this, STRING_T * str, size_t pos,
size_t ns);
STRING_T *DSassignchar (STRING_T * this, int c, size_t n);
STRING_T *DSassigncstr (STRING_T * this, char *s, size_t n);
STRING_T *DSassign (STRING_T * this, STRING_T * str, size_t pos,
size_t ns);
STRING_T *DSinsertchar (STRING_T * this, size_t p0, int c, size_t nr);
STRING_T *DSinsertcstr (STRING_T * this, size_t p0, char *s, size_t
ns);
STRING_T *DSinsert (STRING_T * this, size_t p0, STRING_T * str, size_t
pos,
size_t ns);
STRING_T *DSremove (STRING_T * this, size_t p0, size_t nr);
STRING_T *DSreplacechar (STRING_T * this, size_t p0, size_t n0, int c,
size_t nr);
STRING_T *DSreplacecstr (STRING_T * this, size_t p0, size_t n0, char
*s,
size_t ns);
STRING_T *DSreplace (STRING_T * this, size_t p0, size_t n0, STRING_T *
str,
size_t pos, size_t ns);
int DSget_at (STRING_T * this, size_t p0);
void DSput_at (STRING_T * this, size_t p0, int c);
size_t DScopy (STRING_T * this, char *s, size_t n, size_t p0);
size_t DSfind (STRING_T * this, char *s, size_t p0, size_t n);
size_t DSrfind (STRING_T * this, char *s, size_t p0, size_t n);
size_t DSfind_first_of (STRING_T * this, char *s, size_t p0, size_t
n);
size_t DSfind_last_of (STRING_T * this, char *s, size_t p0, size_t n);
size_t DSfind_first_not_of (STRING_T * this, char *s, size_t p0,
size_t n);
size_t DSfind_last_not_of (STRING_T * this, char *s, size_t p0, size_t
n);
int DScomparechar (STRING_T * this, int c, size_t p0, size_t ns);
int DScomparecstr (STRING_T * this, char *s, size_t p0, size_t ns);
int DScompare (STRING_T * this, STRING_T * str, size_t p0, size_t ns);
char *DScstr (STRING_T * this);
size_t DSlength (STRING_T * this);
void DSresize (STRING_T * this, size_t n, int c);
size_t DSreserve (STRING_T * this);
void DSset_reserve (STRING_T * this, size_t n);
STRING_T *DSsubstr (STRING_T * this, size_t p, size_t n);

#define T STRING_T
#define TS DAS
#define Tassign(x,y) DSassign(x,y,0,NPOS)
#define Tctor(x) DSctor(x)
#define Tdtor(x) DSdtor(x)
#define PROTOS_ONLY
#include "dynarray.h"
#undef T
#undef TS
#undef Tassign
#undef Tctor
#undef Tdtor
#undef PROTOS_ONLY
#endif

/* END OF FILE */

/* dynstr.c -- dynamic string functions

AUTHOR: Gregory Pietsch

*/

/* includes */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defines.h"
#include "dynstr.h"

/* macros */

#define MIN_SIZE 31

/* typedefs */

/* functions */

static void
DStidy (STRING_T * this, int constructed)
{
if (constructed && this->ptr)
free (this->ptr);
this->ptr = 0;
this->len = 0;
this->res = 0;
}

static int
DSgrow (STRING_T * this, size_t n, int trim)
{
size_t osize = this->ptr == 0 ? 0 : this->res;
size_t size;
char *s;

if (n == 0)
{
if (trim && MIN_SIZE < osize)
DStidy (this, 1);
else if (this->ptr)
this->ptr[this->len = 0] = '\0';
return 0;
}
else if (n == osize || n < osize && !trim)
return 1;
else
{
size = this->ptr == 0 && n < this->res ? this->res : n;
if ((size |= MIN_SIZE) == NPOS)
--size;
if ((s = (char *) realloc (this->ptr, size + 1)) == 0
&& (s = (char *) realloc (this->ptr, (size = n) + 1)) == 0)
Nomemory ();
this->ptr = s;
this->res = size;
return 1;
}
}

static void
DSxlen (void)
{
fputs ("string too long\n", stderr);
abort ();
}

static void
DSxran (void)
{
fputs ("invalid string position\n", stderr);
abort ();
}

/* exported functions */

void
DSctor (STRING_T * this)
{
DStidy (this, 0);
}

void
DSctor_with_size (STRING_T * this, size_t n, capacity c)
{
DStidy (this, 0);
this->res = n;
if (c == default_size)
DSassignchar (this, '\0', n);
}

void
DSdtor (STRING_T * this)
{
DStidy (this, 1);
}

STRING_T *
DScreate (void)
{
STRING_T *this = malloc (sizeof (STRING_T));

if (this == 0)
Nomemory ();
DSctor (this);
return this;
}

void
DSdestroy (STRING_T * this)
{
DSdtor (this);
free (this);
}

STRING_T *
DSappendchar (STRING_T * this, int c, size_t nr)
{
size_t n;

if (NPOS - this->len <= nr)
DSxlen ();
if (0 < nr && DSgrow (this, n = this->len + nr, 0))
{
memset (this->ptr + this->len, c, nr);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSappendcstr (STRING_T * this, char *s, size_t ns)
{
size_t n;

if (ns == NPOS)
ns = strlen (s);
if (NPOS - this->len <= ns)
DSxlen ();
if (0 < ns && DSgrow (this, n = this->len + ns, 0))
{
memcpy (this->ptr + this->len, s, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSappend (STRING_T * this, STRING_T * str, size_t pos, size_t ns)
{
size_t n;

if (DSlength (str) < pos)
DSxran ();
n = DSlength (str) - pos;
if (n < ns)
ns = n;
if (NPOS - this->len <= ns)
DSxlen ();
if (0 < ns && DSgrow (this, n = this->len + ns, 0))
{
memcpy (this->ptr + this->len, DScstr (str) + pos, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSassignchar (STRING_T * this, int c, size_t n)
{
if (n == NPOS)
DSxlen ();
if (DSgrow (this, n, 1))
{
memset (this->ptr, c, n);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSassigncstr (STRING_T * this, char *s, size_t n)
{
if (n == NPOS)
n = strlen (s);
if (DSgrow (this, n, 1))
{
memcpy (this->ptr, s, n);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSassign (STRING_T * this, STRING_T * str, size_t pos, size_t ns)
{
size_t n;

if (DSlength (str) < pos)
DSxran ();
n = DSlength (str) - pos;
if (ns < n)
n = ns;
if (this == str)
{
DSremove (this, pos + n, NPOS);
DSremove (this, 0, pos);
}
else if (DSgrow (this, n, 1))
{
memcpy (this->ptr, DScstr (str) + pos, n);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSinsertchar (STRING_T * this, size_t p0, int c, size_t nr)
{
size_t n;

if (this->len < p0)
DSxran ();
if (NPOS - this->len <= nr)
DSxlen ();
if (0 < nr && DSgrow (this, n = this->len + nr, 0))
{
memmove (this->ptr + (p0 + nr), this->ptr + p0, this->len - p0);
memset (this->ptr + p0, c, nr);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSinsertcstr (STRING_T * this, size_t p0, char *s, size_t ns)
{
size_t n;

if (this->len < p0)
DSxran ();
if (ns == NPOS)
ns = strlen (s);
if (NPOS - this->len <= ns)
DSxlen ();
if (0 < ns && DSgrow (this, n = this->len + ns, 0))
{
memmove (this->ptr + (p0 + ns), this->ptr + p0, this->len - p0);
memcpy (this->ptr + p0, s, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSinsert (STRING_T * this, size_t p0, STRING_T * str, size_t pos,
size_t ns)
{
size_t n;

if (this->len < p0 || DSlength (str) < pos)
DSxran ();
n = DSlength (str) - pos;
if (n < ns)
ns = n;
if (NPOS - this->len <= ns)
DSxlen ();
if (0 < ns && DSgrow (this, n = this->len + ns, 0))
{
memmove (this->ptr + (p0 + ns), this->ptr + p0, this->len - p0);
memcpy (this->ptr + p0, DScstr (str) + pos, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSremove (STRING_T * this, size_t p0, size_t nr)
{
size_t n;

if (this->len < p0)
DSxran ();
if (this->len - p0 < nr)
nr = this->len - p0;
if (0 < nr)
{
memmove (this->ptr + p0, this->ptr + (p0 + nr), this->len - p0 -
nr);
n = this->len - nr;
if (DSgrow (this, n, 0))
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSreplacechar (STRING_T * this, size_t p0, size_t n0, int c, size_t
nr)
{
size_t n, nm;

if (this->len < p0)
DSxran ();
if (this->len - p0 < n0)
n0 = this->len - p0;
if (NPOS - nr <= this->len - n0)
DSxlen ();
nm = this->len - n0 - p0;
if (nr < n0)
memmove (this->ptr + (p0 + nr), this->ptr + (p0 + n0), nm);
if ((0 < nr || 0 < n0) && DSgrow (this, n = this->len + nr - n0, 0))
{
if (n0 < nr)
memmove (this->ptr + (p0 + nr), this->ptr + (p0 + n0), nm);
memset (this->ptr + p0, c, nr);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSreplacecstr (STRING_T * this, size_t p0, size_t n0, char *s, size_t
ns)
{
size_t n, nm;

if (this->len < p0)
DSxran ();
if (ns == NPOS)
ns = strlen (s);
if (NPOS - ns <= this->len - n0)
DSxlen ();
nm = this->len - n0 - p0;
if (ns < n0)
memmove (this->ptr + (p0 + ns), this->ptr + (p0 + n0), nm);
if ((0 < ns || 0 < n0) && DSgrow (this, n = this->len + ns - n0, 0))
{
if (n0 < ns)
memmove (this->ptr + (p0 + ns), this->ptr + (p0 + n0), nm);
memcpy (this->ptr + p0, s, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}

STRING_T *
DSreplace (STRING_T * this, size_t p0, size_t n0, STRING_T * str,
size_t pos, size_t ns)
{
size_t n, nm;

if (this->len < p0 || DSlength (str) < pos)
DSxran ();
n = DSlength (str) - pos;
if (n < ns)
ns = n;
if (NPOS - ns <= this->len - n0)
DSxlen ();
nm = this->len - n0 - p0;
if (ns < n0)
memmove (this->ptr + (p0 + ns), this->ptr + (p0 + n0), nm);
if ((0 < ns || 0 < n0) && DSgrow (this, n = this->len + ns - n0, 0))
{
if (n0 < ns)
memmove (this->ptr + (p0 + ns), this->ptr + (p0 + n0), nm);
memcpy (this->ptr + p0, DScstr (str) + pos, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}

int
DSget_at (STRING_T * this, size_t p0)
{
if (this->len <= p0)
DSxran ();
return this->ptr[p0];
}

void
DSput_at (STRING_T * this, size_t p0, int c)
{
if (this->len < p0)
DSxran ();
else if (this->len == p0)
DSappendchar (this, c, 1);
else
this->ptr[p0] = c;
}

size_t
DScopy (STRING_T * this, char *s, size_t n, size_t p0)
{
if (this->len < p0)
DSxran ();
if (this->len - p0 < n)
n = this->len - p0;
memcpy (s, this->ptr + p0, n);
return n;
}

size_t
DSfind (STRING_T * this, char *s, size_t p0, size_t n)
{
size_t nmax;
char *t, *u;

if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (p0 < this->len && n <= (nmax = this->len - p0))
{
for (nmax -= n - 1, u = this->ptr + p0;
(t = (char *) memchr (u, *s, nmax)) != 0;
nmax -= t - u + 1, u = t + 1)
if (memcmp (t, s, n) == 0)
return t - this->ptr;
}
return NPOS;
}

size_t
DSrfind (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t;

if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (n <= this->len)
for (t = this->ptr + (p0 < this->len - n ? p0 : this->len - n);;
--t)
if (*t == *s && memcmp (t, s, n) == 0)
return t - this->ptr;
else if (t == this->ptr)
break;
return NPOS;
}

size_t
DSfind_first_of (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t, *u;

if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (p0 < this->len)
{
u = this->ptr + this->len;
for (t = this->ptr + p0; t < u; t++)
if (memchr (s, *t, n) != 0)
return t - this->ptr;
}
return NPOS;
}

size_t
DSfind_last_of (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t;

if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (0 < this->len)
for (t = this->ptr + (p0 < this->len ? p0 : this->len - 1);; t--)
if (memchr (s, *t, n) != 0)
return t - this->ptr;
else if (t == this->ptr)
break;
return NPOS;
}

size_t
DSfind_first_not_of (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t, *u;

if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (p0 < this->len)
{
u = this->ptr + this->len;
for (t = this->ptr + p0; t < u; t++)
if (memchr (s, *t, n) == 0)
return t - this->ptr;
}
return NPOS;
}

size_t
DSfind_last_not_of (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t;

if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (0 < this->len)
for (t = this->ptr + (p0 < this->len ? p0 : this->len - 1);; t--)
if (memchr (s, *t, n) == 0)
return t - this->ptr;
else if (t == this->ptr)
break;
return NPOS;
}

int
DScomparechar (STRING_T * this, int c, size_t p0, size_t ns)
{
size_t n;
char *s, *t;

if (this->len < p0)
DSxran ();
n = this->len - p0;
for (s = this->ptr + p0, t = s + (n < ns ? n : ns); s < t; s++)
if (*s != c)
return (*(unsigned char *) s < (unsigned char) c ? -1 : 1);
return (n < ns ? -1 : n > ns);
}

int
DScomparecstr (STRING_T * this, char *s, size_t p0, size_t ns)
{
size_t n;
int ans;

if (this->len < p0)
DSxran ();
n = this->len - p0;
if (ns == NPOS)
ns = strlen (s);
ans = memcmp (this->ptr + p0, s, n < ns ? n : ns);
return ans ? ans : n < ns ? -1 : n > ns;
}

int
DScompare (STRING_T * this, STRING_T * str, size_t p0, size_t ns)
{
size_t n;
int ans;

if (this->len < p0)
DSxran ();
n = this->len - p0;
if (DSlength (str) < ns)
ns = DSlength (str);
ans = memcmp (this->ptr + p0, DScstr (str), n < ns ? n : ns);
return ans ? ans : n < ns ? -1 : n > ns;
}

char *
DScstr (STRING_T * this)
{
return this->ptr ? this->ptr : "";
}

size_t
DSlength (STRING_T * this)
{
return this->len;
}

void
DSresize (STRING_T * this, size_t n, int c)
{
if (n < this->len)
DSremove (this, n, NPOS);
else
DSappendchar (this, c, n - this->len);
}

size_t
DSreserve (STRING_T * this)
{
return this->res;
}

void
DSset_reserve (STRING_T * this, size_t n)
{
if (this->ptr == 0)
this->res = n;
}

STRING_T *
DSsubstr (STRING_T * this, size_t p, size_t n)
{
STRING_T *s = DScreate ();

DSassign (s, this, p, n);
return s;
}

#define T STRING_T
#define TS DAS
#define Tassign(x,y) DSassign(x,y,0,NPOS)
#define Tctor(x) DSctor(x)
#define Tdtor(x) DSdtor(x)
#undef PROTOS_ONLY
#include "dynarray.h"
#undef T
#undef TS
#undef Tassign
#undef Tctor
#undef Tdtor

/* END OF FILE */

Gregory Pietsch
Nov 14 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: meyousikmann | last post by:
The following code just sets up and fills a dynamic array of integers. #include <cstdlib> int main() { int* intArray = NULL; int count; count = 20;
4
by: Scott Lyons | last post by:
Hey all, Can someone help me figure out how to pass a dynamic array into a function? Its been giving me some trouble, and my textbook of course doesnt cover the issue. Its probably something...
3
by: genc ymeri | last post by:
Hi, What can I use in C# for dynamic arrays ???? I have some records (struts in ..Net) and want to store them in a dynamic "arrays" or object list. I noticed the in C# arrays' length can't be...
60
by: Peter Olcott | last post by:
I need to know how to get the solution mentioned below to work. The solution is from gbayles Jan 29 2001, 12:50 pm, link is provided below: >...
4
by: learnfpga | last post by:
Here is a little code I wrote to add the numbers input by the user.....I was wondering if its possible to have the same functionality without using dynamic arrays.....just curious..... ...
2
by: assgar | last post by:
Hi Developemnt on win2003 server. Final server will be linux Apache,Mysql and PHP is being used. I use 2 scripts(form and process). The form displays multiple dynamic rows with chechboxs,...
4
by: hobbes992 | last post by:
Howdy folks, I've been working on a c project, compiling using gcc, and I've reached a problem. The assignment requires creation of a two-level directory file system. No files have to be added or...
1
by: KioKrofov | last post by:
Hello, I am trying to find out how Dynamic Arrays are actually stored in memory. Really, I want to know how Vectors are stored in memory, but I deduce they are stored the same way. If you...
2
by: headware | last post by:
Do dynamic arrays declared using ReDim have to be freed? I assume that if it's an array of dynamically created objects (e.g. Scripting.Dictionary), each one of those objects will have to be set to...
4
by: Sunny | last post by:
Hi, Is there a way in javascript to create Dynamic arrays or arrays on fly. Something Like: var "ptsgN"+sd = new Array(); Here sd is incrementing by 1. I have lots of data that I am...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.