home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / libncftp / older_versions / libncftp-3.2.2-src.tar.bz2 / libncftp-3.2.2-src.tar / libncftp-3.2.2 / Strn / Strntok.c < prev    next >
C/C++ Source or Header  |  2001-11-19  |  4KB  |  180 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. /* This version of Strtok differs from the regular ANSI strtok in that
  7.  * an empty token can be returned, and consecutive delimiters are not
  8.  * ignored like ANSI does.  Example:
  9.  *
  10.  * Parse String = ",,mike,gleason,-West Interactive,402-573-1000"
  11.  * Delimiters = ",-"
  12.  *
  13.  * (ANSI strtok:)
  14.  * strtok 1=[mike] length=4
  15.  * strtok 2=[gleason] length=7
  16.  * strtok 3=[West Interactive] length=16
  17.  * strtok 4=[402] length=3
  18.  * strtok 5=[573] length=3
  19.  * strtok 6=[1000] length=4
  20.  * 
  21.  * (Strtok:)
  22.  * Strtok 1=[] length=0
  23.  * Strtok 2=[] length=0
  24.  * Strtok 3=[mike] length=4
  25.  * Strtok 4=[gleason] length=7
  26.  * Strtok 5=[] length=0
  27.  * Strtok 6=[West Interactive] length=16
  28.  * Strtok 7=[402] length=3
  29.  * Strtok 8=[573] length=3
  30.  * Strtok 9=[1000] length=4
  31.  *
  32.  */
  33.  
  34. char *
  35. Strtok(char *buf, const char *delims)
  36. {
  37.     static char *p = NULL;
  38.     char *start, *end;
  39.  
  40.     if (buf != NULL) {
  41.         p = buf;
  42.     } else {
  43.         if (p == NULL)
  44.             return (NULL);        /* No more tokens. */
  45.     }
  46.     for (start = p, end = p; ; end++) {
  47.         if (*end == '\0') {
  48.             p = NULL;        /* This is the last token. */
  49.             break;
  50.         }
  51.         if (strchr(delims, (int) *end) != NULL) {
  52.             *end++ = '\0';
  53.             p = end; 
  54.             break;
  55.         }
  56.     }
  57.     return (start);
  58. }    /* Strtok */
  59.  
  60.  
  61.  
  62.  
  63. /* This is a bounds-safe version of Strtok, where you also pass a pointer
  64.  * to the token to write into, and its size.  Using the example above,
  65.  * with a char token[8], you get the following.  Notice that the token
  66.  * is not overrun, and is always nul-terminated:
  67.  *
  68.  * Strntok 1=[] length=0
  69.  * Strntok 2=[] length=0
  70.  * Strntok 3=[mike] length=4
  71.  * Strntok 4=[gleason] length=7
  72.  * Strntok 5=[] length=0
  73.  * Strntok 6=[West In] length=7
  74.  * Strntok 7=[402] length=3
  75.  * Strntok 8=[573] length=3
  76.  * Strntok 9=[1000] length=4
  77.  */
  78.  
  79. int
  80. Strntok(char *dstTokenStart, size_t tokenSize, char *buf, const char *delims)
  81. {
  82.     static char *p = NULL;
  83.     char *end;
  84.     char *lim;
  85.     char *dst;
  86.     int len;
  87.  
  88.     dst = dstTokenStart;
  89.     lim = dst + tokenSize - 1;        /* Leave room for nul byte. */
  90.  
  91.     if (buf != NULL) {
  92.         p = buf;
  93.     } else {
  94.         if (p == NULL) {
  95.             *dst = '\0';
  96.             return (-1);        /* No more tokens. */
  97.         }
  98.     }
  99.  
  100.     for (end = p; ; end++) {
  101.         if (*end == '\0') {
  102.             p = NULL;        /* This is the last token. */
  103.             break;
  104.         }
  105.         if (strchr(delims, (int) *end) != NULL) {
  106.             ++end;
  107.             p = end; 
  108.             break;
  109.         }
  110.         if (dst < lim)            /* Don't overrun token size. */
  111.             *dst++ = *end;
  112.     }
  113.     *dst = '\0';
  114.     len = (int) (dst - dstTokenStart);        /* Return length of token. */
  115.  
  116. #if (STRN_ZERO_PAD == 1)
  117.     /* Pad with zeros. */
  118.     for (++dst; dst <= lim; )
  119.         *dst++ = 0;
  120. #endif    /* STRN_ZERO_PAD */
  121.  
  122.     return (len);
  123. }    /* Strntok */
  124.  
  125.  
  126.  
  127. #ifdef TESTING_STRTOK
  128. #include <stdio.h>
  129.  
  130. void
  131. main(int argc, char **argv)
  132. {
  133.     char buf[256];
  134.     int i;
  135.     char *t;
  136.     char token[8];
  137.     int tokenLen;
  138.  
  139.     if (argc < 3) {
  140.         fprintf(stderr, "Usage: test \"buffer,with,delims\" <delimiters>\n");
  141.         exit(1);
  142.     }
  143.     strcpy(buf, argv[1]);
  144.     i = 1;
  145.     t = strtok(buf, argv[2]);
  146.     if (t == NULL)
  147.         exit(0);
  148.     do {
  149.         printf("strtok %d=[%s] length=%d\n", i, t, (int) strlen(t));
  150.         t = strtok(NULL, argv[2]);
  151.         ++i;
  152.     } while (t != NULL);
  153.  
  154.     printf("------------------------------------------------\n");
  155.     strcpy(buf, argv[1]);
  156.     i = 1;
  157.     t = Strtok(buf, argv[2]);
  158.     if (t == NULL)
  159.         exit(0);
  160.     do {
  161.         printf("Strtok %d=[%s] length=%d\n", i, t, (int) strlen(t));
  162.         t = Strtok(NULL, argv[2]);
  163.         ++i;
  164.     } while (t != NULL);
  165.  
  166.     printf("------------------------------------------------\n");
  167.     strcpy(buf, argv[1]);
  168.     i = 1;
  169.     tokenLen = Strntok(token, sizeof(token), buf, argv[2]);
  170.     if (tokenLen < 0)
  171.         exit(0);
  172.     do {
  173.         printf("Strntok %d=[%s] length=%d\n", i, token, tokenLen);
  174.         tokenLen = Strntok(token, sizeof(token), NULL, argv[2]);
  175.         ++i;
  176.     } while (tokenLen >= 0);
  177.     exit(0);
  178. }
  179. #endif
  180.