📄 mystring.c
字号:
/* mystring.c Copyright (C) 2002 Georg Post * * This file is part of Numparam, see: readme.txt * Free software under the terms of the GNU Lesser General Public License * $Id: mystring.c,v 1.3 2005/05/22 21:34:01 sjborley Exp $ */#ifdef __TURBOC__extern unsigned _stklen= 32000; /* Turbo C default was only 4 K */#endif#include <stdio.h>#include <stdlib.h>/* #include <math.h> -- ceil floor */#include "config.h"#ifdef HAS_WINDOWS#include "wstdio.h"#endif#include "general.h"#define Getmax(s,ls) (((Byte)(s[ls+1])) Shl 8) + (Byte)(s[ls+2])/***** primitive input-output ***/Proc wc(char c)Begin fputc(c, stdout)EndProcProc wln(void)Begin wc('\n') EndProcProc ws( Pchar s)Begin short k=0; While s[k] !=0 Do wc(s[k]); Inc(k) DoneEndProcProc wi(long i)Begin Str(16,s); nadd(s,i); ws(s)EndProcProc rs( Pchar s)Begin /*basic line input, limit= 80 chars */ short max,i; char c; max=maxlen(s); i=0; sini(s,max); If max>80 Then max=80 EndIf Repeat c=fgetc(stdin); If (i<max) And (c>=' ') Then cadd(s,c); Inc(i) EndIf Until (c==Cr) Or (c=='\n') EndRep /* return i */EndFuncFunc char rc(void)Begin short ls; Str(80,s); rs(s); ls=length(s); If ls>0 Then return s[ls-1] Else return 0 EndIfEndProc/******* Strings ************ * are 0-terminated char arrays with a 2-byte trailer: max length. * the string mini-library is "overflow-safe" under these conditions: * use Str(n,s) macro: define and initialize a string s of maxlen n<255 * use sini() to initialize empty strings; sfix() for non-empty ones. * the Sini() macro does automatic sizing, for automatic char arrays * to allocate a string on the heap, use newstring(n). * use maxlen() and length() to retrieve string max and actual length * use: cadd, cins, sadd, sins, scopy, pscopy to manipulate them * never put '\x0' characters inside strings ! * * the 'killer idea' is the following: * on string overflow and/or on heap allocation failure, a program * MUST die. */Intern Proc stringbug(Pchar op, Pchar s, Pchar t, char c)/* we brutally stop the program on string overflow */Begin char rep=' '; ws(" STRING overflow "); ws(op); wln(); ws(" Operand1: "); ws(s); wln(); If t != Null Then ws(" Operand2: "); ws(t); wln(); EndIf If c != 0 Then wc('{'); wc(c); wc('}') EndIf ws(" [A]bort [I]gnore ? "); rep=rc(); If upcase(rep)=='A' Then exit(1) EndIfEndProcProc sini(Pchar s, short max) /* suppose s is allocated */Begin If max<1 Then max=1 ElsIf max>Maxstr Then max=Maxstr EndIf s[0]=0; s[1]= Hi(max); s[2]= Lo(max);EndProcProc sfix(Pchar s, short i, short max)/* suppose s is allocated and filled with non-zero stuff */Begin short j; If max<1 Then max=1 ElsIf max>Maxstr Then max=Maxstr EndIf If i>max Then i=max ElsIf i<0 Then i=0 EndIf s[i]=0; s[i+1]= Hi(max); s[i+2]= Lo(max); For j=0;j<i; Inc(j) Do /* eliminate null characters ! */ If s[j]==0 Then s[j]=1 EndIf DoneEndProcInternProc inistring(Pchar s, char c, short max)/* suppose s is allocated. empty it if c is zero ! */Begin short i=0; s[i]=c; If c!=0 Then Inc(i); s[i]=0 EndIf If max<1 Then max=1 ElsIf max>Maxstr Then max=Maxstr EndIf s[i+1]= Hi(max); s[i+2]= Lo(max);EndProcFunc short length(Pchar s)Begin short lg=0; While NotZ(s[lg]) Do Inc(lg) Done return lgEndFuncFunc short maxlen(Pchar s)Begin short ls= length(s); return Getmax(s,ls)EndFuncFunc Bool sadd( Pchar s, Pchar t)Begin Bool ok; short i=0, max, ls= length(s); max= Getmax(s,ls); While (t[i] !=0) And (ls<max) Do s[ls]= t[i]; Inc(i); Inc(ls); Done s[ls]=0; s[ls+1]= Hi(max); s[ls+2]= Lo(max); ok= (t[i]==0); /* end of t is reached */ If Not ok Then stringbug("sadd",s,t,0) EndIf return okEndProcFunc Bool cadd( Pchar s, char c)Begin short max, ls= length(s); Bool ok; max= Getmax(s,ls); ok= (ls<max); If ok Then s[ls+3]= s[ls+2]; s[ls+2]=s[ls+1]; s[ls+1]=0; s[ls]=c EndIf If Not ok Then stringbug("cadd",s, Null,c) EndIf return okEndProcFunc Bool cins( Pchar s, char c)Begin short i, max, ls= length(s); Bool ok; max= Getmax(s,ls); ok= (ls<max); If ok Then For i=ls+2; i>=0; Dec(i) Do s[i+1]=s[i] Done; s[0]=c; EndIf If Not ok Then stringbug("cins",s, Null,c) EndIf return okEndProcFunc Bool sins( Pchar s, Pchar t)Begin short i, max, ls= length(s), lt=length(t); Bool ok; max= Getmax(s,ls); ok= ((ls+lt) < max); If ok Then For i=ls+2; i>=0; Dec(i) Do s[i+lt]=s[i] Done; For i=0; i<lt; Inc(i) Do s[i]=t[i] Done; EndIf If Not ok Then stringbug("sins",s, t,0) EndIf return okEndProcFunc short cpos(char c, Pchar s)/* return position of c in s, or 0 if not found. * BUG, Pascal inherited: first char is at 1, not 0 ! */Begin short i=0; While (s[i] !=c) And (s[i] !=0) Do Inc(i) Done If s[i]==c Then return (i+1) Else return 0 EndIfEndFuncFunc char upcase(char c)Begin If (c>='a')And(c<='z') Then return c+'A'-'a' Else return c EndIfEndFuncFunc Bool scopy(Pchar s, Pchar t) /* returns success flag */Begin Bool ok; short i,max, ls= length(s); max= Getmax(s,ls); i=0; While (t[i] !=0) And (i<max) Do s[i]= t[i]; Inc(i); Done s[i]=0; s[i+1]= Hi(max); s[i+2]= Lo(max); ok= (t[i]==0); /* end of t is reached */ If Not ok Then stringbug("scopy",s, t,0) EndIf return okEndProcFunc Bool ccopy(Pchar s, char c) /* returns success flag */Begin short max, ls= length(s); Bool ok=False; max= Getmax(s,ls); If max>0 Then s[0]=c; sfix(s,1,max); ok=True EndIf If Not ok Then stringbug("ccopy",s, Null,c) EndIf return okEndProcFunc Pchar pscopy(Pchar s, Pchar t, short start, short leng)/* partial string copy, with Turbo Pascal convention for "start" *//* BUG: position count starts at 1, not 0 ! */Begin short max= maxlen(s); /* keep it for later */ short stop= length(t); short i; Bool ok= (max>=0) And (max<=Maxstr); If Not ok Then stringbug("copy target non-init", s, t, 0) EndIf If leng>max Then leng=max; ok=False EndIf If start>stop Then /* nothing! */ ok=False; inistring(s,0,max) Else If (start+leng-1)>stop Then leng = stop-start+1; ok=False EndIf For i=0; i<leng; Inc(i) Do s[i]= t[start+i -1] Done i=leng; s[i]=0; s[i+1]= Hi(max); s[i+2]= Lo(max); EndIf /* If Not ok Then stringbug("copy",s, t, 0) EndIf */ /* If ok Then return s Else return Null EndIf */ ok=ok; return sEndProcFunc short ord(char c)Begin return c AND 0xffEndFunc /* strip high byte */Func short pred(short i)Begin return (--i)EndFuncFunc short succ(short i)Begin return (++i)EndFuncFunc Bool nadd( Pchar s, long n)/* append a decimal integer to a string */Begin short d[25]; short j,k,ls,len; char sg; /* the sign */ Bool ok; k=0; len=maxlen(s); If n<0 Then n= -n; sg='-' Else sg='+' EndIf While n>0 Do d[k]=n Mod 10; Inc(k); n= n Div 10 Done If k==0 Then ok=cadd(s,'0') Else ls=length(s); ok= (len-ls)>k; If ok Then If sg=='-' Then s[ls]=sg; Inc(ls) EndIf For j=k-1; j>=0; Dec(j) Do s[ls]=d[j]+'0'; Inc(ls) Done sfix(s,ls,len); EndIf EndIf If Not ok Then stringbug("nadd",s, Null,sg) EndIf return okEndProcProc stri( long n, Pchar s)/* convert integer to string */Begin sini(s, maxlen(s)); nadd(s,n)EndProcProc rawcopy(Pointer a, Pointer b, short la, short lb)/* dirty binary copy */Begin short j,n; If lb<la Then n=lb Else n=la EndIf For j=0; j<n; Inc(j) Do ((Pchar)a)[j]=((Pchar)b)[j] DoneEndProcFunc short scompare(Pchar a, Pchar b)Begin Word j=0; short k=0; While (a[j]==b[j]) And (a[j]!=0) And (b[j]!=0) Do Inc(j) Done; If a[j]<b[j] Then k= -1 ElsIf a[j]>b[j] Then k=1 EndIf return kEndFuncFunc Bool steq(Pchar a, Pchar b) /* string a==b test */Begin Word j=0; While (a[j]==b[j]) And (a[j]!=0) And (b[j]!=0) Do Inc(j) Done; return ((a[j]==0) And (b[j]==0)) /* string equality test */EndFuncFunc Bool stne(Pchar s, Pchar t)Begin return scompare(s,t) !=0EndFuncFunc short hi(long w)Begin return (w AND 0xff00) Shr 8EndFuncFunc short lo(long w)Begin return (w AND 0xff)EndFuncFunc char lowcase(char c)Begin If (c>='A')And(c<='Z') Then return (char)(c-'A' +'a') Else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -