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

📄 tools.h

📁 c语言编写的微型数据库 实现了插入、删除、更新等基本功能
💻 H
字号:
/*这份代码经源码格式软件格式化过
     yang_hx@neusoft.com      */
#ifndef TOOL_H
#define TOOL_H
#include "Glob_Var.H"
/* #include "Std_Head.H" */
/* ----------------------------------------------------------- */
/* 删除在词头尾的空格和控制符(ASCII小于32)*/
void CutBlank_Head_Tail(char*S)
{
    unsigned int i=0,j=strlen(S);
    
    while(((unsigned char)S[i]<=32)&&(i<j))i++;
    
    while(((unsigned char)S[j]<=32)&&(i<j))j--;
    
    strncpy(S,&S[i],j-i+1);
    
    S[j-i+1]=0 ;
    /* 复制中间一段 */
}

/* ------------------------------------------------------------- */
/* 删除词头的',' */
void CutComma(char*S)
{
    int n ;
    
    n=strlen(S);
    
    if(S[0]==',')strncpy(S,&S[1],n-1);
    
    S[n-1]='\0' ;
}

/* ----------------------------------------------------------------- */
int CountSymbol(char*S,char C)
{
    /* 计算S中字符C的个数 */
    int i,count=0 ;
    
    for(i=0;i<strlen(S);i++)
    
    if(S[i]==C)count++;
    
    return count ;
}

/* --------------------------------------------------------------------- */
int GetSubStr_By_Delimitor(char*S,int*ScanPos,char*Delimitor,char*SubStr)

/*根据分隔符集合Delimitor,在串S中的扫描起点ScanPos后,取出子串SubStr,并且移动

  扫描起点到新的位置 ,用于词法分析,注意,Scan是指针,将修改被指物 *ScanPos */

{
    int SubStrBegin,len,ok,InStr=FALSE ;
    
    len=strlen(S);
    /* 串长,下句跳过前面的分隔符(但在双引号中的分隔符除外)*/
    
    while((*ScanPos<len)&&
    (strchr(Delimitor,*(S+(*ScanPos)))!=NULL))
    
    {
        if(*(S+(*ScanPos))=='\"')InStr=!InStr ;
        /*双引号中的分隔符除外*/
        
        (*ScanPos)++;
    }
    
    SubStrBegin=*ScanPos ;
    /* 子串开始, 扫描子串,包括双引号中的分隔符 */
    
    while((*ScanPos<=len)&&(InStr||(strchr(Delimitor,*(S+*ScanPos))==NULL)))
    {
        if(*(S+(*ScanPos))=='\"')InStr=!InStr ;
        /*包括双引号中的分隔符*/
        
        (*ScanPos)++;
    }
    
    strncpy(SubStr,S+SubStrBegin,*ScanPos-SubStrBegin);
    /* 复制子串 */
    
    *(SubStr+*ScanPos-SubStrBegin)='\0' ;
    /* 串尾加0 */
    
    ok=((strcmp(SubStr,"")!=0)&&(*ScanPos<=len));
    
    return(ok);
}
/* GetSubStr_By_delimit */

/* -------------------------------------------------------------------------------- */
int GetSubStr_Between(char*S,int*ScanPos,char Delim1,char Delim2,char*SubStr)

/*在串S中的扫描起点Scan后,取出在分隔符Delim1和Delim2之间的子串SubStr,并且移动

  扫描起点到新的位置 ,用于词法分析,分隔符常为引号或括号,注意,Scan是指针,将修

  改被指物 *Scan */

{
    int Left,Right,Len ;
    
    Left=*ScanPos ;
    /* 左边为扫描起点  */
    Len=strlen(S);
    
    if(Len==0)
    {
        *SubStr='\0' ;
        return(TRUE);
    }
    
    while((Left<Len)&&
    (Delim1!=S[Left]))++Left ;
    if(S[Left]!=Delim1)return(0);
    /* 验明左边分隔符 */
    
    Right=Left+1 ;
    
    while(Right<Len&&
    S[Right]!=Delim2)++Right ;
    
    if(S[Right]!=Delim2)return(0);
    /* 验明右边分隔符 */
    
    strncpy(SubStr,&S[Left+1],Right-Left-1);
    /* 复制子串 */
    
    SubStr[Right-Left-1]=0 ;
    
    *ScanPos=Right+1 ;
    
    return(1);
    /* 移动扫描点 */
    
}
/* GetOneWord between two deliminators*/

/* --------------------------------------------------------------------------- */
int GetSubStr_By_ValidChar(char*S,int*ScanPos,char*ValidCh,char*SubStr)

/*在串S中的扫描点Scan后,取出由合法字符集合ValidCh 组成的子串SubStr,并且移动

  扫描点到新的位置 ,用于词法分析,合法字符常为 "1234567890." 等等,注意,Scan是

  指针,将修改被指物 *Scan */

{
    int Left,Len ;
    
    Len=strlen(S);
    
    *SubStr='\0' ;
    
    while(*ScanPos<Len&&strchr(ValidCh,S[ScanPos])==NULL)
    
    ++(*ScanPos);
    
    Left=*ScanPos ;
    /*记住合法字符开始位置 */
    
    while(*ScanPos<Len&&
    (strchr(ValidCh,S[*ScanPos])!=NULL))
    
    ++(*ScanPos);
    
    strncpy(SubStr,&S[Left],*ScanPos-Left);
    /*复制子串 */
    
    SubStr[*ScanPos-Left]=0 ;
    
    return(*ScanPos-Left);
    
}
/* GetSubStr_by_ValidChar */
/* -------------------------------------------------------------------- */
/* void InitCmdRec(CmdRec_Type CmdRec) */

    /* 初始化命令记录结构 */
/*    CmdRec.Cmd_N=10 ;
    
    CmdRec.UserStr="" ;
    
    CmdRec.Fld=NULL = "";
    
    *CmdRec.FldValue[0]='\0' ;
    
    CmdRec.Range[0]="" ;
    
    CmdRec.Phase[0]="" ;
    
    CmdRec.Exp[0]="" ;

    CmdRec.Token1[0] = "";

    CmdRec.Count = 0;
}*/

/* ---------------------------------------------------------------------- */
void CloseWA( )                                 /* 关闭工作区 */

 {
   if ( WA[0] == NULL) return;

   fclose( WA[0]->DbFi_P);   WA[0]->DbFi_P=NULL; /* 关关闭数据文件*/

    WA[0]=NULL; }
/* -------------------------------------------------------------------------- */
void  Init_CmdRec(CmdRec_Type CmdRec) /* 把命令行记录,即分析结果清0 */

{  memset(&CmdRec,0,sizeof(CmdRec));}/*Init_CmdRec*/

/*-------------------------------------------------------------------------*/

void    ClearCmdRec(CmdRec_Type CmdRec) /* 回收CmdRec中分配的指针空间并清0 */

{
   int I;

   for(I=1;I<=MaxFldNum;I++)
     {
       free(CmdRec.FldValue[I]);CmdRec.FldValue[I]=NULL;}

       CmdRec.Fld = NULL;

       memset(&CmdRec,0,sizeof(CmdRec));}/*ClearCmdRec()*/


/* ---------------------------------------------------------------------------- */
int vssf(char*Token,char*fmt,...)
{
    va_list argptr ;
    
    int cnt ;
    
    fflush(stdin);
    
    va_start(argptr,fmt);
    
    cnt=vsscanf(Token,fmt,argptr);
    
    va_end(argptr);
    
    return(cnt);
}


/* 通过字符串string,分别对各个参数进行赋值,参数从Vlist param中取得 */
FldInfor_T To_Fld_Str(char*Token,int i)
{
    CmdRec_Type CmdRec2 ;
    
    vssf(Token,"%s %s %d ",CmdRec2.Fld[i].FldName,CmdRec2.Fld[i].FldClass,&CmdRec2.Fld[i].FldLen);
    
    return CmdRec2.Fld[i];
}
/* ------------------------------------------------------------------------------------ */

/* 将第i个字段信息数组Token的字段名,字段类型,整数和小数长度存入结构中,供建表使用(有小数) */
FldInfor_T To_Fld_Str1(char*Token,int i)
{
    CmdRec_Type CmdRec1 ;
    
    vssf(Token,"%s %s %d %d",CmdRec1.Fld[i].FldName,CmdRec1.Fld[i].FldClass,&CmdRec1.Fld[i].FldLen,&CmdRec1.Fld[i].DicimalLen);
    
    return CmdRec1.Fld[i];
}
/* ------------------------------------------------------------------------------------- */
FldInfor_T*Change(char*Token1)
{
    /* 将字段信息放入CmdRec的字段结构数组中 */
    
    FldInfor_T FldVal[15];
    /*  字段信息结构数组 */
    
    int i,TokenPos,count,count1 ;
    
    char Token[20][50];
    
    FldInfor_T ptr ;
    
    count=CountSymbol(Token1,',');
    /* 计算','个数,从而得知字段数 */
    
    Token1[strlen(Token1)]=',' ;
    
    Token1[strlen(Token1)+1]='\0' ;
    
    for(i=1;i<=count+1;i++)
    
    {
        CutBlank_Head_Tail(Token);
        
        CutComma(Token1);
        
        TokenPos=0 ;
        
        GetSubStr_By_Delimitor(Token1,&TokenPos,",",Token[i]);
        /* 取得起始位置到','之间的记录信息,包括字段名,字段类型,字段长度(float型有整数和小数长度之分) */
        
        strncpy(Token1,&Token1[strlen(Token[i])],strlen(Token1)-strlen(Token[i])+1);
        
        count1=CountSymbol(Token[i],' ');
        
        /* 不是float型(如sna char 10),可以得到记录结构字段名,字段类型,字段长度,存入一结构中 */
        if(count1==2)
        {
            ptr=To_Fld_Str(Token[i],i);
            ptr.DicimalLen=0 ;
        }
        
        
        /* 是浮点型(如score float 5 2),可以得到记录结构字段名,字段类型,整数和小数长度 */
        else 
        ptr=To_Fld_Str1(Token[i],i);
        
        FldVal[i]=ptr ;
        
    }
    
    return FldVal ;
}
/* ----------------------------------------------------------------------------- */
char(*Value(char*Token))[15][30]
{
    /* 将用户插入的记录值分别存入CmdRec结构的FldValue中,供插入时使用 */
    
    int TokenPos,i,n,m ;
    
    static char ha[15][30];
    /*   */
    
    n=strlen(Token);
    
    m=CountSymbol(Token,',');
    
    Token[n]=',' ;
    
    Token[n+1]='\0' ;
    
    for(i=1;i<=m+1;i++)
    {
        
        CutBlank_Head_Tail(Token);
        
        TokenPos=0 ;
        
        GetSubStr_By_Delimitor(Token,&TokenPos,",",ha[i]);
        /* 取得起始位置到','之间的记录值 */
        
        strncpy(Token,&Token[strlen(ha[i])],strlen(Token)-strlen(ha[i])+1);
        /* 记录数组向前移 */
        
        CutBlank_Head_Tail(Token);
        
        CutComma(Token);
    }
    return ha ;
}
/* --------------------------------------------------------------------------------------------- */
/* 变文件名Path的扩展名为Ext */
char*ChangeExt(char*Path,char*Ext)
{
    char Dir[80],Fi_name[13],Ext_Old[5],Drive[3];
    
    fnsplit(Path,Drive,Dir,Fi_name,Ext_Old);
    /* 分解数据文件名 */
    
    fnmerge(Path,Drive,Dir,Fi_name,Ext);
    /* 再用新的扩展名合成 */
    
    return(Path);
}
/* -------------------------------------------------------- */
#endif

⌨️ 快捷键说明

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