Dynamic Arrays

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Materialised

    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%c codegurus%corg% c", "ma", 58, "mi", 64,
    46, 10;'
  • Serve Laurijssen

    #2
    Re: Dynamic Arrays

    "Materialis ed" <Materialised@p rivacy.net> wrote in message
    news:c65ppe$88b bk$1@ID-220437.news.uni-berlin.de...[color=blue]
    > 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.[/color]

    #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);
    }
    }


    Comment

    • Thapani Sawaengsri

      #3
      Re: Dynamic Arrays


      "Materialis ed" <Materialised@p rivacy.net> wrote in message
      news:c65ppe$88b bk$1@ID-220437.news.uni-berlin.de...[color=blue]
      > 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.[/color]

      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(&presid ent,"George Washington");
      addNAME(&presid ent,"Abe Lincoln");
      puts("President s in the array are");
      for(i = 0; i < president.count ;i++)
      printf("\t%s\n" ,president.name[i]);
      freeNAME(&presi dent);
      printf("\nAfter freeing the array\n"
      "There are %u names in the array\n",presid ent.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)*siz eof(*p->name))) == NULL)
      return NULL;
      if((tmp[i] = malloc(strlen(n ame)+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.


      Comment

      • Dan Pop

        #4
        Re: Dynamic Arrays

        In <c65ppe$88bbk$1 @ID-220437.news.uni-berlin.de> Materialised <Materialised@p rivacy.net> writes:
        [color=blue]
        >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?[/color]

        Yes, you can use a pointer to arrays of that size.
        [color=blue]
        >And if so could someone post a simple example for me, to
        >base my own code off.[/color]

        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: Dan.Pop@ifh.de

        Comment

        • Materialised

          #5
          Re: Dynamic Arrays

          Dan Pop wrote:[color=blue]
          > In <c65ppe$88bbk$1 @ID-220437.news.uni-berlin.de> Materialised <Materialised@p rivacy.net> writes:
          >
          >[color=green]
          >>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?[/color]
          >
          >
          > Yes, you can use a pointer to arrays of that size.
          >
          >[color=green]
          >>And if so could someone post a simple example for me, to
          >>base my own code off.[/color]
          >
          >
          > 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[/color]
          Thanks dan that clarified it for me, and thanks to the other posters as
          well.

          --
          ------
          Materialised

          perl -e 'printf "%silto%c%sck%c codegurus%corg% c", "ma", 58, "mi", 64,
          46, 10;'

          Comment

          • Rakesh Kumar

            #6
            Re: Dynamic Arrays



            Materialised wrote:
            [color=blue]
            > 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.[/color]
            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 **

            Comment

            • Gregory Pietsch

              #7
              Re: Dynamic Arrays

              Materialised <Materialised@p rivacy.net> wrote in message news:<c65ppe$88 bbk$1@ID-220437.news.uni-berlin.de>...[color=blue]
              > 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[/color]

              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:


              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_siz e (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_no t_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_siz e (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_no t_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

              Comment

              Working...