• 程序实践系列之库源码


    /*
     * File: stdgen.h
     * -----------------------------------------------------
     * The basic definitions provided by stdgen.h are:
     *
     *    1.  Declarations for several new "primitive" types
     *        (most importantly string) that are
     *        used throughout the other libraries and
     *        applications as fundamental types.
     *
     *    2.  A new set of functions for memory allocation.
     *
     *    3.  A function for error handling.
     *
     *    4.  A repeat statement for loops with interior exits.
     */
    
    #ifndef _stdgen_h
    #define _stdgen_h
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stddef.h>
    
    /* Section 1: Define new "primitive" types */
    
    /* Type: bool
     *--------------------
     *
     */
    #ifdef T_C
      typedef int bool
    #else
    #  ifdef TRUE
    #	  ifndef bool
    #	    define bool int
    #	  endif
    #  else
    #    ifdef bool
    #       define FALSE 0
    #       define TRUE 1
    #    else
           typedef enum{ FALSE,TRUE} bool;
    #    endif
    #  endif
    #endif
    
    
    /*
     * Type: string
     * ------------
     * The type string is identical to the type char *, which is
     * traditionally used in C programs.  The main point of defining a
     * new type is to improve program readability.   At the abstraction
     * levels at which the type string is used, it is usually not
     * important to take the string apart into its component characters.
     * Declaring it as a string emphasizes this atomicity.
     */
    
    typedef char *string;
    
    /*
     * Type: stream
     * ------------
     * Like string, the stream type is used to provide additional
     * readability and is defined to be equivalent to FILE *
     * (which is particularly confusing because it violates
     * standard case conventions).  This type is not used in
     * the text but is preserved in genlib.h, so it is possible
     * to teach all of CS1 without exposing any pointers.
     */
    
    typedef FILE *stream;
    
    /*
     * Constant: UNDEFINED
     * -------------------
     * Besides NULL, the only other constant of pointer type is
     * UNDEFINED, which is used in certain packages as a special
     * sentinel to indicate an undefined pointer value.  In many
     * such contexts, NULL is a legitimate data value and is
     * therefore inappropriate as a sentinel.
     */
    
    #define UNDEFINED ((void *) undefined_object)
    
    extern char undefined_object[];
    
    /* Section 2: Memory allocation */
    
    /*
     * General notes:
     * --------------
     * These functions provide a common interface for memory
     * allocation.  All functions in the library that allocate
     * memory do so using GetBlock and FreeBlock. 
     */
    
    /*
     * Function: GetBlock
     * Usage: ptr = (type) GetBlock(nbytes);
     * -------------------------------------
     * GetBlock allocates a block of memory of the given size.  If
     * no memory is available, GetBlock generates an error.
     */
    
    void *GetBlock(size_t nbytes);
    
    /*
     * Function: FreeBlock
     * Usage: FreeBlock(ptr);
     * ----------------------
     * FreeBlock frees the memory associated with ptr, which must
     * have been allocated using GetBlock, New, or NewArray.
     */
    
    void FreeBlock(void *ptr);
    
    /*
     * Macro: New
     * Usage: p = New(pointer-type);
     * -----------------------------
     * The New pseudofunction allocates enough space to hold an
     * object of the type to which pointer-type points and returns
     * a pointer to the newly allocated pointer.  Note that
     * "New" is different from the "new" operator used in C++;
     * the former takes a pointer type and the latter takes the
     * target type.
     */
    
    #define New(type) ((type) GetBlock(sizeof *((type) NULL)))
    
    /*
     * Macro: NewArray
     * Usage: p = NewArray(n, element-type);
     * -------------------------------------
     * NewArray allocates enough space to hold an array of n
     * values of the specified element type.
     */
    
    #define NewArray(n, type) ((type *) GetBlock((n) * sizeof (type)))
    
    /* Section 3: Basic error handling */
    
    /*
     * Function: Error
     * Usage: Error(msg, ...)
     * ----------------------
     * Error generates an error string, expanding % constructions
     * appearing in the error message string just as printf does.
     * If an error handler exception has been introduced, the 
     * ErrorException exception is raised with the expanded error
     * string as argument.  If there is no ErrorException defined, 
     * the program exits with a status code indicating failure.  
     * The length of  the error message string following expansion 
     * must not exceed MaxErrorMessage, and it is the client's 
     * responsibility to ensure this.
     */
    
    void Error(string msg, ...);
    
    /* Section 4:The repeat pseudo-statement */
    
    /*
     * Statement form: repeat { ... }
     * ------------------------------
     * Some instructors who have taught CS1 using this library
     * have found that using
     *
     *     while (TRUE)
     *
     * to initiate a loop with an interior exit is confusing to
     * students, particularly when it comes at the beginning of
     * the course.  This macro defines "repeat" as an infinite
     * loop construct for instructors who find it easier to
     * explain, although it is not used in the text.   Similar
     * macro definitions are common in industry.
     */
    
    #define repeat for (;;)
    
    #endif /*stdgenlib.h*/
    

    /*
     * File: stdgen.c
     * -----------------------------------------------------
     * This file implements the general C library package.  See the
     * interface description in stdgen.h for details.
     */
    
    #include <stdio.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdarg.h>
    
    #include "stdgen.h"
    
    /*
     * Constants:
     * ----------
     * ErrorExitStatus -- Status value used in exit call
     * MaxErrorMessage -- Longest error message allowed
     */
    
    #define ErrorExitStatus 1
    #define MaxErrorMessage 500
    
    /* Section 1: Define new "primitive" types */
    
    /*
     * Constant: UNDEFINED
     * -------------------
     * This entry defines the target of the UNDEFINED constant.
     */
    
    char undefined_object[] = "UNDEFINED";
    
    /* Section 2: Memory allocation */
    
    /*
     * Implementation notes:
     * ---------------------
     * The code for the memory allocator is  The
     * intention is to minimize the size of object files
     * produced by linkers that search a library for modules
     * that are actually referenced.  
     */
    
    /* Memory allocation implementation */
    
    void *GetBlock(size_t nbytes)
    {
        void *result;
    	
    	result = malloc(nbytes);
        if (result == NULL) 
    		Error("No memory available");
        return (result);
    }
    
    void FreeBlock(void *ptr)
    {
    	free(ptr);
    }
    
    /* Section 3:Basic error handling */
    
    /*
     * Implementation notes: Error
     * ---------------------------
     * Writing the Error function requires some care, since it is
     * called in circumstances in which parts of the system may be
     * broken.  In particular, it is not acceptable for Error to
     * call GetBlock, since the error condition may be that the
     * system is out of memory, in which case calling GetBlock would
     * fail.  The error string should be allocated dynamically,
     * so that this function can be used in reentrant code.
     * Note that it is critical to exit if the length bound for
     * an error message is exceeded, since this error almost
     * certainly corrupts the stack.
     */
    
    void Error(string msg, ...)
    {
        va_list args;
    
    	va_start(args,msg);
    	fprintf(stderr,"Error: ");
    	vfprintf(stderr,msg,args);
    	fprintf(stderr,"
    ");
    	va_end(args);
    	exit(ErrorExitStatus);
    }
    


    /*
     * File: stdstr.h
     * -----------------------------------------------------
     * The strlib.h file defines the interface for a simple
     * string library.  In the context of this package, strings
     * are considered to be an abstract data type, which means
     * that the client relies only on the operations defined for
     * the type and not on the underlying representation.
     */
    
    /*
     * Cautionary note:
     * ----------------
     * Although this interface provides an extremely convenient
     * abstraction for working with strings, it is not appropriate
     * for all applications.  In this interface, the functions that
     * return string values (such as Concat and SubString) do so
     * by allocating new memory.  Over time, a program that uses
     * this package will consume increasing amounts of memory
     * and eventually exhaust the available supply.  If you are
     * writing a program that runs for a short time and stops,
     * the fact that the package consumes memory is not a problem.
     * If, however, you are writing an application that must run
     * for an extended period of time, using this package requires
     * that you make some provision for freeing any allocated
     * storage.
     */
    
    #ifndef _stdstr_h
    #define _stdstr_h
    
    #include "stdgen.h"
    
    /* Section 1:Basic string operations */
    
    /*
     * Function: Concat
     * Usage: s = Concat(s1, s2);
     * --------------------------
     * This function concatenates two strings by joining them end
     * to end.  For example, Concat("ABC", "DE") returns the string
     * "ABCDE".
     */
    
    string Concat(string s1, string s2);
    
    /*
     * Function: IthChar
     * Usage: ch = IthChar(s, i);
     * --------------------------
     * This function returns the character at position i in the
     * string s.  It is included in the library to make the type
     * string a true abstract type in the sense that all of the
     * necessary operations can be invoked using functions. Calling
     * IthChar(s, i) is like selecting s[i], except that IthChar
     * checks to see if i is within the range of legal index
     * positions, which extend from 0 to StringLength(s).
     * IthChar(s, StringLength(s)) returns the null character
     * at the end of the string.
     */
    
    char IthChar(string s, int i);
    
    /*
     * Function: SubString
     * Usage: t = SubString(s, p1, p2);
     * --------------------------------
     * SubString returns a copy of the substring of s consisting
     * of the characters between index positions p1 and p2,
     * inclusive.  The following special cases apply:
     *
     * 1. If p1 is less than 0, it is assumed to be 0.
     * 2. If p2 is greater than the index of the last string
     *    position, which is StringLength(s) - 1, then p2 is
     *    set equal to StringLength(s) - 1.
     * 3. If p2 < p1, SubString returns the empty string.
     */
    
    string SubString(string s, int p1, int p2);
    
    /*
     * Function: CharToString
     * Usage: s = CharToString(ch);
     * ----------------------------
     * This function takes a single character and returns a
     * one-character string consisting of that character.  The
     * CharToString function is useful, for example, if you
     * need to concatenate a string and a character.  Since
     * Concat requires two strings, you must first convert
     * the character into a string.
     */
    
    string CharToString(char ch);
    
    /*
     * Function: StringLength
     * Usage: len = StringLength(s);
     * -----------------------------
     * This function returns the length of s.
     */
    
    int StringLength(string s);
    
    /*
     * Function: CopyString
     * Usage: newstr = CopyString(s);
     * ------------------------------
     * CopyString copies the string s into dynamically allocated
     * storage and returns the new string.  This function is not
     * ordinarily required if this package is used on its own,
     * but is often necessary when you are working with more than
     * one string package.
     */
    
    string CopyString(string s);
    
    /* Section 2: String comparison functions */
    
    /*
     * Function: StringEqual
     * Usage: if (StringEqual(s1, s2)) ...
     * -----------------------------------
     * This function returns TRUE if the strings s1 and s2 are
     * equal.  For the strings to be considered equal, every
     * character in one string must precisely match the
     * corresponding character in the other.  Uppercase and
     * lowercase characters are considered to be different.
     */
    
    bool StringEqual(string s1, string s2);
    
    /*
     * Function: StringCompare
     * Usage: if (StringCompare(s1, s2) < 0) ...
     * -----------------------------------------
     * This function returns a number less than 0 if string s1
     * comes before s2 in alphabetical order, 0 if they are equal,
     * and a number greater than 0 if s1 comes after s2.  The
     * ordering is determined by the internal representation used
     * for characters, which is usually ASCII.
     */
    
    int StringCompare(string s1, string s2);
    
    /* Section 3:Search functions */
    
    /*
     * Function: FindChar
     * Usage: p = FindChar(ch, text, start);
     * -------------------------------------
     * Beginning at position start in the string text, this
     * function searches for the character ch and returns the
     * first index at which it appears or -1 if no match is
     * found.
     */
    
    int FindChar(char ch, string text, int start);
    
    /*
     * Function: FindString
     * Usage: p = FindString(str, text, start);
     * ----------------------------------------
     * Beginning at position start in the string text, this
     * function searches for the string str and returns the
     * first index at which it appears or -1 if no match is
     * found.
     */
    
    int FindString(string str, string text, int start);
    
    /* Section 4: Case-conversion functions */
    
    /*
     * Function: ConvertToLowerCase
     * Usage: s = ConvertToLowerCase(s);
     * ---------------------------------
     * This function returns a new string with all
     * alphabetic characters converted to lower case.
     */
    
    string ConvertToLowerCase(string s);
    
    /*
     * Function: ConvertToUpperCase
     * Usage: s = ConvertToUpperCase(s);
     * ---------------------------------
     * This function returns a new string with all
     * alphabetic characters converted to upper case.
     */
    
    string ConvertToUpperCase(string s);
    
    /* Section 5: Functions for converting numbers to strings */
    
    /*
     * Function: IntegerToString
     * Usage: s = IntegerToString(n);
     * ------------------------------
     * This function converts an integer into the corresponding
     * string of digits.  For example, IntegerToString(123)
     * returns "123" as a string.
     */
    
    string IntegerToString(int n);
    
    /*
     * Function: StringToInteger
     * Usage: n = StringToInteger(s);
     * ------------------------------
     * This function converts a string of digits into an integer.
     * If the string is not a legal integer or contains extraneous
     * characters, StringToInteger signals an error condition.
     */
    
    int StringToInteger(string s);
    
    /*
     * Function: RealToString
     * Usage: s = RealToString(d);
     * ---------------------------
     * This function converts a floating-point number into the
     * corresponding string form.  For example, calling
     * RealToString(23.45) returns "23.45".  The conversion is
     * the same as that used for "%G" format in printf.
     */
    
    string RealToString(double d);
    
    /*
     * Function: StringToReal
     * Usage: d = StringToReal(s);
     * ---------------------------
     * This function converts a string representing a real number
     * into its corresponding value.  If the string is not a
     * legal floating-point number or if it contains extraneous
     * characters, StringToReal signals an error condition.
     */
    
    double StringToReal(string s);
    
    #endif
    

    /*
     * File: stdstr.c
     * -----------------------------------------------------
     * This file implements the stdstr.h interface.
     *
     * General implementation notes:
     * -----------------------------
     * This module implements the stdstr library by mapping all
     * functions into the appropriate calls to the ANSI <string.h>
     * interface.  The implementations of the individual functions
     * are all quite simple and do not require individual comments.
     * For descriptions of the behavior of each function, see the
     * interface.
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    #include "stdgen.h"
    #include "strlib.h"
    
    /*
     * Constant: MaxDigits
     * -------------------
     * This constant must be larger than the maximum
     * number of digits that can appear in a number.
     */
    
    #define MaxDigits 30
    
    /* Private function prototypes */
    
    static string CreateString(int len);
    
    /* Section 1: Basic string operations */
    
    string Concat(string s1, string s2)
    {
        string s;
        int len1, len2;
    
        if (s1 == NULL || s2 == NULL) {
            Error("NULL string passed to Concat");
        }
        len1 = strlen(s1);
        len2 = strlen(s2);
        s = CreateString(len1 + len2);
    
        strcpy(s, s1);
        strcpy(s + len1, s2);
        return (s);
    }
    
    char IthChar(string s, int i)
    {
        int len;
    
        if (s == NULL) Error("NULL string passed to IthChar");
        len = strlen(s);
        if (i < 0 || i > len) {
            Error("Index outside of string range in IthChar");
        }
        return (s[i]);
    }
    
    string SubString(string s, int p1, int p2)
    {
        int len;
        string result;
    
        if (s == NULL) Error("NULL string passed to SubString");
        len = strlen(s);
        if (p1 < 0) p1 = 0;
        if (p2 >= len) p2 = len - 1;
        len = p2 - p1 + 1;
        if (len < 0) len = 0;
        result = CreateString(len);
        strncpy(result, s + p1, len);
        result[len] = '';
        return (result);
    }
    
    string CharToString(char ch)
    {
        string result;
    
        result = CreateString(1);
        result[0] = ch;
        result[1] = '';
        return (result);
    }
    
    int StringLength(string s)
    {
        if (s == NULL) Error("NULL string passed to StringLength");
        return (strlen(s));
    }
    
    string CopyString(string s)
    {
        string newstr;
    
        if (s == NULL) Error("NULL string passed to CopyString");
        newstr = CreateString(strlen(s));
        strcpy(newstr, s);
        return (newstr);
    }
    
    /* Section 2 : String comparison functions */
    
    bool StringEqual(string s1, string s2)
    {
        if (s1 == NULL || s2 == NULL) {
            Error("NULL string passed to StringEqual");
        }
        return (strcmp(s1, s2) == 0);
    }
    
    int StringCompare(string s1, string s2)
    {
        if (s1 == NULL || s2 == NULL) {
            Error("NULL string passed to StringCompare");
        }
        return (strcmp(s1, s2));
    }
    
    /* Section 3 : Search functions */
    
    int FindChar(char ch, string text, int start)
    {
        char *cptr;
    
        if (text == NULL) Error("NULL string passed to FindChar");
        if (start < 0) start = 0;
        if (start > strlen(text)) return (-1);
        cptr = strchr(text + start, ch);
        if (cptr == NULL) return (-1);
        return ((int) (cptr - text));
    }
    
    int FindString(string str, string text, int start)
    {
        char *cptr;
    
        if (str == NULL) Error("NULL pattern string in FindString");
        if (text == NULL) Error("NULL text string in FindString");
        if (start < 0) start = 0;
        if (start > strlen(text)) return (-1);
        cptr = strstr(text + start, str);
        if (cptr == NULL) return (-1);
        return ((int) (cptr - text));
    }
    
    /* Section 4 : Case-conversion functions */
    
    string ConvertToLowerCase(string s)
    {
        string result;
        int i;
    
        if (s == NULL) {
            Error("NULL string passed to ConvertToLowerCase");
        }
        result = CreateString(strlen(s));
        for (i = 0; s[i] != ''; i++) result[i] = tolower(s[i]);
        result[i] = '';
        return (result);
    }
    
    string ConvertToUpperCase(string s)
    {
        string result;
        int i;
    
        if (s == NULL) {
            Error("NULL string passed to ConvertToUpperCase");
        }
        result = CreateString(strlen(s));
        for (i = 0; s[i] != ''; i++) result[i] = toupper(s[i]);
        result[i] = '';
        return (result);
    }
    
    /* Section 5 : Functions for converting numbers to strings */
    
    string IntegerToString(int n)
    {
        char buffer[MaxDigits];
    
        sprintf(buffer, "%d", n);
        return (CopyString(buffer));
    }
    
    int StringToInteger(string s)
    {
        int result;
        char dummy;
    
        if (s == NULL) {
            Error("NULL string passed to StringToInteger");
        }
        if (sscanf(s, " %d %c", &result, &dummy) != 1) {
            Error("StringToInteger called on illegal number %s", s);
        }
        return (result);
    }
    
    string RealToString(double d)
    {
        char buffer[MaxDigits];
    
        sprintf(buffer, "%G", d);
        return (CopyString(buffer));
    }
    
    double StringToReal(string s)
    {
        double result;
        char dummy;
    
        if (s == NULL) Error("NULL string passed to StringToReal");
        if (sscanf(s, " %lg %c", &result, &dummy) != 1) {
            Error("StringToReal called on illegal number %s", s);
        }
        return (result);
    }
    
    /* Private functions */
    
    /*
     * Function: CreateString
     * Usage: s = CreateString(len);
     * -----------------------------
     * This function dynamically allocates space for a string of
     * len characters, leaving room for the null character at the
     * end.
     */
    
    static string CreateString(int len)
    {
        return ((string) GetBlock(len + 1));
    }
    


  • 相关阅读:
    STL中string的源码解读
    Sublime插件:Terminal
    sublime text3安装Package Control
    [转]Sublime Text操作
    python itertools模块实现排列组合
    pandas 选择某几列
    更改pandas dataframe 列的顺序
    pandas之groupby分组与pivot_table透视表
    IPython notebook快捷键(Jupyter notebook)
    人生的意义
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5249749.html
Copyright © 2020-2023  润新知