⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sfltok.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  ----------------------------------------------------------------<Prolog>-
    Name:       sflenv.c
    Title:      String token manipulation functions.
    Package:    Standard Function Library (SFL)

    Written:    1996/09/10  iMatix SFL project team <sfl@imatix.com>
    Revised:    2000/01/11

    Copyright:  Copyright (c) 1996-2000 iMatix Corporation
    License:    This is free software; you can redistribute it and/or modify
                it under the terms of the SFL License Agreement as provided
                in the file LICENSE.TXT.  This software is distributed in
                the hope that it will be useful, but without any warranty.
 ------------------------------------------------------------------</Prolog>-*/

#include "prelude.h"                    /*  Universal header file            */
#include "sflstr.h"                     /*  Conversion functions             */
#include "sfllist.h"                    /*  Linked-list functions            */
#include "sflmem.h"                     /*  Memory allocation functions      */
#include "sflsymb.h"                    /*  Symbol table functions           */
#include "sfltok.h"                     /*  Prototypes for functions         */


/*  ---------------------------------------------------------------------[<]-
    Function: tok_split

    Synopsis: Accepts a string and breaks it into words, delimited by white
    space (spaces, tabs, newlines).  Returns an array of strings which ends
    in a NULL string.  If the string is empty or NULL, returns an array
    containing a single NULL value.  The array is allocated dynamically by
    this function, and you must call tok_free() to release it when you have
    finished.  Returns NULL if there was insufficient memory to complete the
    split operation.
    ---------------------------------------------------------------------[>]-*/

char **
tok_split (
    const char *string)
{
    char
        *buffer,
        *bufptr,
        **token_list,                   /*  Returned token list              */
        last_char = '\0';               /*  Last character parsed            */
    int
        word_count = 0,                 /*  Number of words in string        */
        word_nbr;

    /*  Allocate space for work string, up to the size of the input string   */
    if (string == NULL)
        string = "";

    buffer = mem_alloc (strlen (string) + 1);
    if (buffer == NULL)
        return (NULL);

    /*  Now copy string and eliminate whitespace                             */
    bufptr = buffer;                    /*  Move to start of target buffer   */
    while (*string)                     /*  Copy entire string               */
        if (isspace (*string))          /*  Collapse whitespace to           */
          {                             /*    a single null byte             */
            while (isspace (*string))
                string++;
            if (bufptr > buffer)
              {
                word_count++;           /*  We have a new word               */
                last_char = *bufptr++ = '\0';
              }
          }
        else
            last_char = *bufptr++ = *string++;

    /*  Count last word if it was not terminated in a white space            */
    if (last_char > 0)
        word_count++;
    *bufptr = '\0';                     /*  End with final NULL              */

    /*  The token list starts with a pointer to the buffer, then has one     */
    /*  pointer to each string in the buffer.  It ends with a null pointer.  */
    /*  We return the address of the first string pointer, i.e. the caller   */
    /*  does not see the pointer to the buffer.  We can thus get away with   */
    /*  just two allocs; one for the buffer and one for the token list.      */
    token_list = mem_alloc (sizeof (char *) * (word_count + 2));
    if (token_list == NULL)
        return (NULL);

    token_list [0] = buffer;            /*  Store buffer address             */
    token_list++;                       /*    and bump starting address      */

    bufptr = buffer;
    for (word_nbr = 0; word_nbr < word_count; word_nbr++)
      {
        token_list [word_nbr] = bufptr;
        bufptr += strlen (bufptr) + 1;
      }
    token_list [word_count] = NULL;     /*  Store final null pointer         */
    return (token_list);
}


/*  ---------------------------------------------------------------------[<]-
    Function: tok_split_rich

    Synopsis: Works as the tok_split() function, but handles tokens that are
    delimited by user-specified characters.  A typical use of this function
    is to handle quoted strings.  Each character in the delims argument is a
    potential token delimiter.  For instance, to handle strings defined with
    single or double quotes, you could pass "\"'" as the delims argument.
    Note that this function always splits on spaces outside delimited tokens.
    ---------------------------------------------------------------------[>]-*/

char **
tok_split_rich (
    const char *string,
    const char *delims)
{
    char
        *buffer,
        *bufptr,
        **token_list,                   /*  Returned token list              */
        delim,                          /*  Current delimiter character      */
        last_char = '\0';               /*  Last character parsed            */
    int
        word_count = 0,                 /*  Number of words in string        */
        word_nbr;

    /*  Allocate space for work string, up to the size of the input string   */
    buffer = mem_alloc (strlen (string) + 1);
    if (buffer == NULL)
        return (NULL);

    /*  Now copy string and eliminate spaces and cut on delimiters           */
    bufptr = buffer;                    /*  Move to start of target buffer   */
    if (string)                         /*  Allow string to be NULL          */
      {
        while (*string)                 /*  Copy entire string               */
            if (strchr (delims, *string))
              {                         /*  User-specified delimiter         */
                word_count++;           /*  Count the word                   */
                delim = *string++;      /*    and skip the delimiter         */
                while (*string != delim)
                  {
                    if (*string)
                        *bufptr++ = *string++;
                    else
                        break;          /*  Unfinished token, but allright   */
                  }
                last_char = *bufptr++ = '\0';
                if (*string == delim)
                    string++;           /*  Skip final delimiter             */
                while (isspace (*string))
                    string++;           /*    and any trailing spaces        */
              }
            else
            if (isspace (*string))      /*  Collapse whitespace to           */
              {                         /*    a single null byte             */
                word_count++;           /*    unless at the start            */
                while (isspace (*string))
                    string++;
                if (bufptr > buffer)
                    last_char = *bufptr++ = '\0';
              }
            else
                last_char = *bufptr++ = *string++;
      }
    /*  Count last word if it was not terminated in a white space            */
    if (last_char > 0)
        word_count++;

    *bufptr = '\0';                     /*  End with final NULL              */

    /*  The token list starts with a pointer to the buffer, then has one     */
    /*  pointer to each string in the buffer.  It ends with a null pointer.  */
    /*  We return the address of the first string pointer, i.e. the caller   */
    /*  does not see the pointer to the buffer.  We can thus get away with   */
    /*  just two allocs; one for the buffer and one for the token list.     */
    token_list = mem_alloc (sizeof (char *) * (word_count + 2));
    if (token_list == NULL)
        return (NULL);

    token_list [0] = buffer;            /*  Store buffer address             */
    token_list++;                       /*    and bump starting address      */

    bufptr = buffer;
    for (word_nbr = 0; word_nbr < word_count; word_nbr++)
      {
        token_list [word_nbr] = bufptr;
        bufptr += strlen (bufptr) + 1;
      }
    token_list [word_count] = NULL;     /*  Store final null pointer         */
    return (token_list);

}

/*  ---------------------------------------------------------------------[<]-
    Function: tok_free

    Synopsis: Frees the memory allocated by a tok_split() call.  You should
    call this function for each call to tok_split(), to avoid memory leaks.
    Do not try to free the allocated memory yourself, as the structure of a
    token list is not documented and may change over time.
    ---------------------------------------------------------------------[>]-*/

void
tok_free (
    char **token_list)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -