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

📄 sflstr.c

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

    Written:    1992/10/28  iMatix SFL project team <sfl@imatix.com>
    Revised:    1999/09/02

    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 "sfllist.h"                    /*  Linked-list functions            */
#include "sflmem.h"                     /*  Memory handling functions        */
#include "sflsymb.h"                    /*  Symbol-table functions           */
#include "sfltok.h"                     /*  Token-handling functions         */
#include "sflstr.h"                     /*  Prototypes for functions         */

/*  Globals                                                                  */
char *xstrcpy_file = "";                /*  Source file calling xstrcpy      */
word  xstrcpy_line = 0;                 /*  Source line for call             */


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

    Synopsis:
    Makes a duplicate of string, obtaining space with a call to malloc().
    The allocated space is strlen (string) + 1 bytes long.  The caller is
    responsible for freeing the space allocated by strdup when it is no
    longer needed.  Returns a pointer to the allocated string, which holds
    a copy of the parameter string.  Returns NULL if there was insufficient
    heap storage available to allocate the string, or if the original string
    was itself NULL.

    Use this function in place of the non-portable strdup() function.  You
    may also want to use the more robust _mem_strdup () function.
    ---------------------------------------------------------------------[>]-*/

char *
strdupl (
    const char *string)
{
    char *copy;
    size_t length;

    if (string)
      {
        length = strlen (string) + 1;
        copy = malloc (length);
        if (copy)
            strncpy (copy, string, length);
      }
    else
        copy = NULL;

    return (copy);
}


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

    Synopsis:
    Releases memory occupied by a string.  Call this function only when you
    previously allocated the string using malloc or strdupl().  You pass the
    address of a char pointer; this function sets the pointer to NULL.  This
    is a safety measure meant to make it safe to try to free non-allocated
    strings.  In your code, initialise all such pointers to NULL.  Returns
    the address of the modified pointer.
    ---------------------------------------------------------------------[>]-*/

char **
strfree (
    char **string)
{
    ASSERT (string);
    if (string && *string)
      {
        free (*string);
        *string = NULL;
      }
    return (string);
}


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

    Synopsis: Skips leading spaces in string, and returns a pointer to the
    first non-blank character.  If this is a null, the end of the string
    was reached.
    ---------------------------------------------------------------------[>]-*/

char *
strskp (
    const char *string)
{
    char
        *skip = (char *) string;

    ASSERT (string);
    while (*skip == ' ')
        skip++;
    return (skip);
}


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

    Synopsis: Sets all characters in string up to but not including the
    final null character to ch.  Returns string.  Use this function instead
    of the equivalent but non-portable strset() function.
    ---------------------------------------------------------------------[>]-*/

char *
strcset (
    char *string,
    char ch)
{
    char *scan;

    ASSERT (string);
    scan = string;
    while (*scan)
        *scan++ = ch;
    return (string);
}


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

    Synopsis: Returns string of length characters, padding with ch or
    truncating if necessary.  String must be at least length + 1 long.
    ---------------------------------------------------------------------[>]-*/

char *
strpad (
    char *string,
    char ch,
    int  length)
{
    int cursize;

    ASSERT (string);
    cursize = strlen (string);          /*  Get current length of string     */
    while (cursize < length)            /*  Pad until at desired length      */
        string [cursize++] = ch;

    string [cursize++] = '\0';          /*  Add terminating null             */
    return (string);                    /*    and return to caller           */
}


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

    Synopsis: Converts all alphabetic characters in string to lowercase,
    stopping at the final null character.  Returns string.  If string is
    null, returns null.  We do not call this function strlwr because that
    is already provided by some systems (but not by ANSI C).
    ---------------------------------------------------------------------[>]-*/

char *
strlwc (
    char *string)
{
    char *scan;

    if (string)
      {
        scan = string;
        while (*scan)
          {
            *scan = (char) tolower (*scan);
            scan++;
          }
      }
    return (string);
}


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

    Synopsis: Converts all alphabetic characters in string to uppercase,
    stopping at the final null character.  Returns string.  If string is
    null, returns null.  We do not call this function strupr because that
    is already provided by some systems (but not by ANSI C).
    ---------------------------------------------------------------------[>]-*/

char *
strupc (
    char *string)
{
    char *scan;

    if (string)
      {
        scan = string;
        while (*scan)
          {
            *scan = (char) toupper (*scan);
            scan++;
          }
      }
    return (string);
}


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

    Synopsis: Drops trailing whitespace from string by truncating string
    to the last non-whitespace character.  Returns string.  If string is
    null, returns null.
    ---------------------------------------------------------------------[>]-*/

char *
strcrop (
    char *string)
{
    char *last;

    if (string)
      {
        last = string + strlen (string);
        while (last > string)
          {
            if (!isspace (*(last - 1)))
                break;
            last--;
          }
        *last = 0;
      }
    return (string);
}


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

    Synopsis: Inserts a character at string, and places a blank in the gap.
    If align is TRUE, makes room by reducing the size of the next gap of 2
    or more spaces.  If align is FALSE, extends the size of the string.
    Returns string.
    ---------------------------------------------------------------------[>]-*/

char *
stropen (
    char *string,
    Bool  align)
{
    char *gap;
    int  length;

    ASSERT (string);
    length = strlen (string) + 1;       /*  By default, move string + NULL   */
    if (align)                          /*  If align is TRUE, find gap       */
      {
        gap = strstr (string, "  ");
        if (gap)
            length = (int) (gap - string);
      }
    memmove (string + 1, string, length);
    string [0] = ' ';                   /*  Stick a space into string        */
    return (string);
}


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

    Synopsis: Removes the character at string, and shifts the remainder
    down by one.  If align is TRUE, only shifts up to the next gap of 2 or
    more spaces.  Returns string.
    ---------------------------------------------------------------------[>]-*/

char *
strclose (
    char *string,
    Bool align)
{
    char *gap;
    int  length;

    ASSERT (string);
    length = strlen (string);           /*  By default, move string + NULL   */
    if (align) {                        /*  If align is TRUE, find gap       */
        gap = strstr (string, "  ");
        if (gap && gap != string)
            length = (int) (gap - string);
    }
    memmove (string, string + 1, length);
    return (string);
}


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

    Synopsis: Reduces chains of some character to a single instances.
    For example: replace multiple spaces by one space.  Returns string.
    ---------------------------------------------------------------------[>]-*/

char *
strunique (
    char *string,
    char  unique)
{
    char
        *from,
        *to;

    ASSERT (string);
    if (strnull (string))
        return (string);                /*  Get rid of special cases         */

    from = string + 1;
    to   = string;
    while (*from)
      {
        if (*from == unique && *to == unique)
            from++;
        else
            *++to = *from++;
      }
    *++to = '\0';
    return (string);
}


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

    Synopsis: Calculates a similarity index for the two strings.  This
    is a value from 0 to 32767 with higher values indicating a closer match.
    The two strings are compared without regard for case.  The algorithm was
    designed by Leif Svalgaard <leif@ibm.net>.
    ---------------------------------------------------------------------[>]-*/

int
strmatch (
    const char *string1,
    const char *string2)
{
    static int
        name_weight [30] = {
            20, 15, 13, 11, 10, 9, 8, 8, 7, 7, 7, 6, 6, 6, 6,
             6,  5,  5,  5,  5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4
        };
    int
        comp_index,
        name_index,
        start_of_string,
        longest_so_far,
        substring_contribution,
        substring_length,
        compare_length,
        longest_length,
        length_difference,
        name_length,
        char_index,
        similarity_index,
        similarity_weight;
    char
        cur_name_char;

    ASSERT (string1);
    ASSERT (string2);

    name_length    = strlen (string1);
    compare_length = strlen (string2);
    if (name_length > compare_length)
      {
        length_difference = name_length - compare_length;
        longest_length    = name_length;
      }
    else
      {
        length_difference = compare_length - name_length;
        longest_length    = compare_length;
      }
    if (compare_length)
      {
        similarity_weight = 0;
        substring_contribution = 0;

        for (char_index = 0; char_index < name_length; char_index++)
          {
            start_of_string = char_index;
            cur_name_char   = (char) tolower (string1 [char_index]);
            longest_so_far  = 0;
            comp_index      = 0;

            while (comp_index < compare_length)
              {
                while ((comp_index < compare_length)
                &&     (tolower (string2 [comp_index]) != cur_name_char))
                    comp_index++;

                substring_length = 0;
                name_index = start_of_string;

                while ((comp_index < compare_length)
                &&     (tolower (string2 [comp_index])
                     == tolower (string1 [name_index])))
                  {
                    if (comp_index == name_index)
                        substring_contribution++;
                    comp_index++;
                    if (name_index < name_length)
                      {
                        name_index++;
                        substring_length++;
                      }
                  }
                substring_contribution += (substring_length + 1) * 3;
                if (longest_so_far < substring_length)
                    longest_so_far = substring_length;
              }
            similarity_weight += (substring_contribution
                                  + longest_so_far + 1) * 2;
            similarity_weight /= name_length + 1;
          }
        similarity_index  = (name_length < 30? name_weight [name_length]: 3)
                          * longest_length;
        similarity_index /= 10;
        similarity_index += 2 * length_difference / longest_length;
        similarity_index  = 100 * similarity_weight / similarity_index;
      }
    else
        similarity_index = 0;

    return (similarity_index);
}


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

    Synopsis: If string starts with specified prefix, returns TRUE.  If
    string does not start with specified prefix, returns FALSE.
    ---------------------------------------------------------------------[>]-*/

Bool
strprefixed (

⌨️ 快捷键说明

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