操作系统接口:Windows命令接口3 课程设计

课程设计的要求
1.为Unix/Linux操作系统建立兼容的Windows/DOS命令接口
2.批处理文件中的流程命令批处理文件的扩展名为.BATCH
3.具体命令:IF, FOR,WHILE,SET,SHIFT,ECHO, GOTO,:(标号),命令格式可参照 Windows 的 CMD.EXE 或 MS-DOS 提供的命令;
4.设计命令的名称、参数等格式。
5.可以执行扩展名为.BATCH的批处理文件。

注:笔者说明
该题目的本质是一个编译原理的课设题。
在但是由于笔者太菜,在课设临近demo时候,词法分析写的乱七八糟。所以最后三天强行改变了方式,仅用了最朴素的分析方式完成,并不是完整版本。
有疑问与交流寄信 SherryBk20

1.对题目要求的说明

第一部分:手动输入batch文件名,读入bat文件,并存储文件结果。
第二部分:词法分析,对语法的分析,并且将其指向到各个功能。
第三部分:IF, FOR,WHILE,SET,SHIFT,ECHO, GOTO,:(标号)等功能的实现。
第四部分:将运算结果输出出来。

2.对实现batch功能的说明

1.echo语句的语法规则

覆盖写入文件(即将某个特定的字符串写入某文件中):echo 字符串 > 文件路径和文件名
输出结果字符串(将字符串结果直接输出):echo 字符串
输出某变量的值:echo %var%

2.goto语句语法规则(包含:label)

跳转到label标号的位置:goto label
跳转位置的标明方法::+符号 如 :label

3.set语句语法规则

set //输出所有已设置的变量的名称
set c  //输出所有以该字符开头的变量的名称
set \a %var% = 1    //设置一个名称为var 的数值变量
set \p %var% = asfd    //设置一个名称为var 的字符串变量
set %1 = ???  //设置一个标号为数字的变量内容。

4.shift语句语法规则

会将 %3 移位到 %2,将 %4 移位到 %3,等等;即将所有的数字变量的值都左移一位。

5.if语句语法规则

类似于c语言的if用法
If范例:

if "%1"=="" goto printHelp
if "%2"=="" goto printHelp
if "%1"=="" echo aaaaaaaaaaaaaaaaaa
if "%2"=="" echo bbbbbbbbbbbbbbbbbb
if "%3"=="" echo cccccccccccccccccc

6.for语句语法规则

(1). /l 迭代数值范围

迭代数值范围
使用迭代变量设置起始值(Start#),然后逐步执行一组范围的值,直到该值超过所设置的终止值 (End#)。/L 将通过对 Start# 与 End# 进行比较来执行迭代变量。如果 Start# 小于 End#,就会执行该命令。
如果迭代变量超过End#,则命令解释程序退出此循环。还可以使用负的 Step#以递减数值的方式逐步执行此范围内的值。例如(1,1,5)生成序列 1 2 3 4 5,而 (5,-1,1) 则生成序列 (5 4 3 2 1)。语法是:
系统帮助的格式:for /L%% Variable in (Start#,Step#,End#) do Command
例如:
for /l %%i in (1,1,5) do @echo %%i
保存执行看效果,他会打印从1 2 3 4 5 这样5个数字
(1,1,5)这个参数也就是表示从1开始每次加1直到5终止!

(2). /f 读取指定文件中的内容

FOR /F “eol=; tokens=2,3 delims= “ %i in (myfile.txt) do @echo %i
实现功能:
分析 myfile.txt 中的每一行,忽略以分号打头的那些行,以delims所标注的分隔符进行分割,将每行中的tokens所标明的第n列字符传递给for函数体。对于带有空格的文件名,您需要用双引号将文件名括起来。
还可以在相邻字符串上使用 FOR /F 分析逻辑,方法是,用单引号将括号之间的 file-set 括起来。这样,该字符串会被当作一个文件中的一个单一输入行进行解析。

(3). /r 递归扫描所有文件

进入根目录树[Drive:]Path,在树的每个目录中执行for 语句。如果在 /R 后没有指定目录,则认为是当前目录。如果 Set 只是一个句点 (.),则只枚举目录树。
系统帮助的格式:FOR /R[[drive:]path] %%variable IN (set) DO command

(4). /d 扫描当前目录下的所有文件夹
for /d %%i in (window?) do @echo %%I

在()中指定的目录下寻找文件夹,如果没有设定并为缺省项,则在默认目录下寻找。

3.程序思路

按行执行命令,首先扫描第一个以空格为分割的字符,判断它是属于哪一种功能的,然后调用到各个具体的函数中执行词法分析。将每一行的内容存储为全局变量,方便每一阶段的函数对语句的具体内容进行调取与分析。
后面进行各个语句的分析。以字符是否存在为表现,进行功能的划分。
(好吧很傻逼别吐槽了)

4.(以下见丑了)程序结构体说明

1.结构体存储从batch文件中读入的每一行内容 word[],并用全局变量count进行计数

struct A{
    char sentence[100];
    char *mystr[20]; //存储每个字符(按照空格分开)
    int numcount;
}word[100];
static int count;

2.存储以数字命名的变量 charater_num[]

struct C_int{
    int flag;
    char contant[10];
}charater_num[10];

3.存储set定义的字符变量 store_str[],并用全局变量number_str进行计数

struct B_char{
    char flag[30]; //未知数标号
    char contant[30];
}store_str[100];
static int number_str;

4.存储set定义的数值变量 store_num[],并用全局变量number_num进行计数

struct B_int{
    char flag[30];
    char contant[30];
}store_num[100];
static int number_num;

5.程序函数说明

1. operater.h

该文件包含一些基础基本函数的实现
函数清单:

void seperate(char *str,int line) //按照分隔符空格将每一行代码开头的标示,如for、if、:label等分割出来,方便进行函数功能体的判断
int char_tran(char x) //将字符转化为数字
char int_tran(int x) //将数字转化为字符
void find_doc2(char *che,char *str) 
void find_doc1(char *str) //扫描默认地址下的文件
(注:由于需要递归,所以必须将默认地址的函数单独拿出来重写)
void find_doc4(char *che)//扫描指定地址下的文件夹
int find_doc5(char *che,char *doc)
//判断指定地址下有没有该名称文件,如果有返回1,如果没有返回0
char str_front(char *str)//取出字符串开头的字符
char str_rear(char *str)//取出字符串结尾的字符
char *str_cut(char *str)//将字符串头和尾的字符去掉

2. func.h(功能介绍)

该文件包含除了for if以外基本功能的实现
函数列表:
//寻找某个标志的变量,如寻找var2标志的变量,返回var2对应的值asdf
char *find_charater(char *str) 
//实现echo的功能
void func_echo(int line)
int str_judge(char *str,char *judge)
void func_set(int line)
int func_goto(char *str,int line)
void func_shift(int line)

3. for_if.h if的所有功能实现(功能介绍)

该文件包含了if功能的实现,由于较为复杂所以单独列出来。
包含了扫描文件的功能。

int goto_if(int line)
char * goto_if_find(int line)
int flag_if_define(char *str)
int flag_if_define2(int line)
int find_if_doc(int line)
void echo_if(int line,int n)
void func_if_exist(int line)
void func_if_char(int line)
int func_if_char1(int line)
void func_if_equal(int line)
void func_if_define(int line)
void func_if(int line)
int func_if_goto(int line)

4. for_for.h for的所有功能实现(功能介绍)

该文件包含了for功能的实现,由于较为复杂所以单独列出来。
包含了扫描文件的功能。

void func_for_d(int line)
void func_for_r(int line)
void func_for_i(int line)
void func_for_l(int line)
void func_for_f1(int line,char *doc)
void func_for_f2(int line,char *doc)
void func_for_f(int line)
void func_for(int line)

5. main.c(功能介绍)

主要进行new.bat文件的读入以及首位字符功能的判断
函数:负责判断首个指定字符串,以判断该行执行的功能。
特殊格式:goto语句的处理
执行其他函数的时候用void语句,执行goto语句的时候最终返回的值是label所载的行数。将扫描的行数i返回到相应行进行扫描。

6.源码

自行取用,用的时候改一下,代码段已上传,注意文件名称的输入。
并且改动一下operater.h中所有的文件名称。(其实不应该这么写的,笔者太菜,有建议寄信)
https://github.com/Sherrybkar/Compile_win-unix_forbatch

1.main.c

#include <stdio.h>
#include "for_for.h"
#include "for_if.h"
void tran()
{
    
}
int main() {
    
    FILE *fp = NULL;
    char buff[664];
    count = 0;
    char doc[30];
    printf("the file input:");
    scanf("%s",doc);
    fp = fopen(doc,"r");
    //读入 
    do
    {
        fgets(buff, 255, (FILE*)fp);
        if (!feof(fp))
        {
            strcpy(word[count].sentence, buff);
            del_char(word[count].sentence, '\n');
            seperate(word[count].sentence,count);
            count++;
        }
    }while (!feof(fp));
    //初始化
    func_shift_ori();
    /*
    for (int i = 0;i<count;i++)
    {
        printf("%s",word[count].sentence);
    }
     */
    //printf("count:%d",count);
    fclose(fp);
    for (int i = 0;i<count;i++)
    {
        if (!strcmp(word[i].mystr[0],"echo"))
        {
            func_echo(i);
            continue;
        }
        if (!strcmp(word[i].mystr[0],"set")) func_set(i);
        //for 的各种职能,在for_if 中进行实现
        if (!strcmp(word[i].mystr[0],"for"))
        {
            func_for(i);
        }
        if (!strcmp(word[i].mystr[0],"if"))
        {
            //如果中间含有goto需要返回line值
            if (goto_if(i))
            {
                i = func_if_goto(i);
            }
            else{
                func_if(i);
            }
            
        }
        if (!strcmp(word[i].mystr[0],"shift"))
        {
            func_shift(i);
        }
        if (!strcmp(word[i].mystr[0],"goto"))
        {
            i = func_goto(word[i].mystr[1],i);
        }
    }
    
    return 0;
}

2.func.h

#ifndef func_h
#define func_h

//echo 的功能实现
#include "operater.h"
//存储set的字符串数值
struct B_char{
    char flag[30]; //未知数标号
    char contant[30];
}store_str[100];
static int number_str;

//存储变量
struct B_int{
    char flag[30];
    char contant[30];
}store_num[100];
static int number_num;

//%1 这种标号的数据存储
struct C_int{
    int flag;
    char contant[10];
}charater_num[10];

//寻找某个标志的变量
char *find_charater(char *str)
{
    for (int i = 0;i<number_num;i++)
    {
        if (!strcmp(store_num[i].flag,str))
        {
            return store_num[i].contant;
        }
    }
    for (int i = 0;i<number_str;i++)
    {
        if (!strcmp(store_str[i].flag,str))
        {
            return store_str[i].contant;
        }
    }
    return NULL;
}
//echo 的功能设计
void func_echo(int line)
{
    for (int i=1;i<word[line].numcount;i++)
    {
        char ch2[30];
        strcpy(ch2,word[line].mystr[1]);
        if ((ch2[0] == '%') && (ch2[strlen(ch2)-1] == '%' ))
        {
            char *ch1;
            ch1=str_cut(ch2);
            printf("%s",find_charater(ch1));
            continue;
        }
        if ((ch2[0] == '%'))
        {
            int j;
            j = char_tran(ch2[1]);
            printf("%s",charater_num[j].contant);
            continue;
        }
        printf("%s ",word[line].mystr[i]);
    }
    printf("\n");
}
//

//set中的对它是否与条件c匹配的判断 set c
//set 的格式为
//set....
int str_judge(char *str,char *judge)
{
    if (strlen(judge)>strlen(str)) return 0;
    char *judgement; //judgement 为从原来的flag的前端截取的,与judge等长的字符串
    memset(judgement, '\0', sizeof(judgement));
    judgement = strncpy(judgement, str, strlen(judge));
    if (!strcmp(judgement, judge)) return 1;  //为1符合
    return 0;
}

void func_set(int line)
{
    //输出所有已经设定好的变量的判断
    //set
    if (word[line].numcount==1)
    {
        for (int i = 0; i < number_num;i++)
        {
            printf("%s\t\t%s\n",store_num[i].flag,store_num[i].contant);
        }
        for (int i = 0; i < number_str;i++)
        {
            printf("%s\t\t%s\n",store_str[i].flag,store_str[i].contant);
        }
        return;
    }
    //输出与条件符合的设定变量的判断
    //set c
    if (word[line].numcount == 2)
    {
        char *judgestr;//set 给出的判断
        judgestr = word[line].mystr[1];
        for (int i = 0; i < number_num;i++)
        {
            if (str_judge(store_num[i].flag,judgestr))
            {
                printf("%s\t%s\n",store_num[i].flag,store_num[i].contant);
            }
        }
        for (int i = 0; i < number_str;i++)
        {
            if (judgestr == store_str[i].flag)
            {
                printf("%s\t%s\n",store_str[i].flag,store_str[i].contant);
            }
        }
        return;
    }
    //set \p var = 1234
    
    if (!strcmp(word[line].mystr[1],"\\p"))
    {
        strcpy(store_str[number_str].flag, word[line].mystr[2]);
        strcpy(store_str[number_str].contant, word[line].mystr[4]);
        number_str++;
    }
    //set \a var = 1243
    if (!strcmp(word[line].mystr[1],"\\a"))
    {
        strcpy(store_num[number_num].flag, word[line].mystr[2]);
        /*
        int x;
        x=char_tran(word[line].mystr[4]);
        store_num[number_num].contant = x;
         */
        strcpy(store_num[number_num].contant, word[line].mystr[4]);
        number_num++;
    }
}



//执行goto职能
int func_goto(char *str,int line)
{
    memset(ch, '\0', sizeof(ch));
    strcpy(ch, ":");
    strcat(ch,str);

    for (int i = 0;i<count;i++)
    {
        if (!strcmp(word[i].mystr[0],ch)) return i;
    }
    return line;
}

//执行shift职能
void func_shift_ori()
{
    char ch6;
    char *ch7;
    for (int i = 0;i<10;i++)
    {
        memset(charater_num[i].contant, '\0', sizeof(charater_num[i].contant));
        charater_num[i].flag = i;
        ch6 = int_tran(i);
        charater_num[i].contant[0]=ch6;
    }
}
void func_shift(int line)
{
    for (int i = 0;i<9;i++)
    {
        strcpy(charater_num[i].contant, charater_num[i+1].contant);
    }
}

3.operater.h

#ifndef operater_h
#define operater_h
//删除语句中的空格
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

char ch[50];  //常常使用

char * deleteSpace(char * str)
{
    char * tail = str;
    char * next = str;
    while(*next){ // 两个if可以合并到一块儿,这样写只是为了看着方便
        if(*next != '\n'){ // 查找不是空格的字符
            *tail = *next;
            tail++;
        }
        next++;
    }
    *tail='\0'; // 字符串结束
    return str;
}
void del_char(char a[],char c)
{
    int i,j;
    for(i=0,j=0; *(a+i)!='\0'; i++)
    {
          if(*(a+i)==c)
             continue;
         else
         {
             *(a+j)=*(a+i);
             j++;
         }
     }
     *(a+j)='\0';
}


//存储每行数据的位置
struct A{
    char sentence[100];
    char *mystr[20]; //存储每个字符(按照空格分开)
    int numcount;
}word[100];
static int count;
//所有的字符数据都存储在
//将所在行按照空格拆分

void seperate(char *str,int line)
{
    const char s[2] = " ";
    char *token;
    
    /* 获取第一个子字符串 */
    token = strtok(str, s);
    
    /* 继续获取其他的子字符串 */
    while( token != NULL ) {
        word[line].mystr[word[line].numcount] = token;
        word[line].numcount++;
        token = strtok(NULL, s);
    }
}

int char_tran(char x)
{
    int i = 0;
    i = x - '0';
    return i;
}


//貌似用不上的数字转制
char int_tran(int x)
{
    char i;
    i = '0'+x;
    return i;
}


//规定了寻找的目录的复杂版本
void find_doc2(char *che,char *str) //复杂版本
{
   // if (!strcmp(str,"*.*"))
    DIR    *dir;
    struct    dirent    *ptr;
    dir = opendir(che); ///open the dir
    //const char str[] = "*.*";
    const char ch1 = '.';
    char *retmain;
    char *ret;
    retmain = strchr(str, ch1);
    if (!strcmp(retmain,".*"))
    {
        while((ptr = readdir(dir)) != NULL) ///read the list of this dir
        {
            ret = strchr(ptr->d_name,ch1);
            if (ret==NULL)
            {
                char dircha[100];
                //char *dir2;
                strcpy(dircha,che);
                strcat(dircha, "/");
                strcat(dircha, ptr->d_name);
                find_doc2(dircha,str);
                
            //方法说明 在原来的路径下面加上 /mylife
                //到下一级路径
                //程序编程使用递归的方法
                //没有使用队列的方法
                //printf("d_name: %s\n",ptr->d_name);
                continue;
            }
            if (*ret == '.' && *(ret+1) && (*(ret+1) != '.') )
            {
                printf("r_name: %s\n",ptr->d_name);
                //printf("d_name: %s\n",ptr->d_name);
            }
        }
        return;
    }
    //".txt"
    while((ptr = readdir(dir)) != NULL) ///read the list of this dir
    {
        ret = strchr(ptr->d_name,ch1);
        if (ret==NULL)
        {
            char dircha[100];
            //char *dir2;
            strcpy(dircha,che);
            strcat(dircha, "/");
            strcat(dircha, ptr->d_name);
            find_doc2(dircha,str);
            continue;
        }
        if (!strcmp(ret, retmain))
        {
            printf("r_name: %s\n",ptr->d_name);
            //printf("d_name: %s\n",ptr->d_name);
        }
    }
    return;
    closedir(dir);
    printf("hello");
}

void find_doc1(char *str) //简单版本的寻找文件
{
   // if (!strcmp(str,"*.*"))
    DIR    *dir;
    struct    dirent    *ptr;
    dir = opendir("/Users/sherry/Desktop/文件夹/text/dict"); ///open the dir
    //const char str[] = "*.*";
    const char ch1 = '.';
    char *retmain;
    char *ret;
    retmain = strchr(str, ch1);
    if (!strcmp(retmain,".*"))
    {
        while((ptr = readdir(dir)) != NULL) ///read the list of this dir
        {
            ret = strchr(ptr->d_name,ch1);
            if (ret==NULL)
            {
                char dircha[100];
                //char *dir2;
                strcpy(dircha,"/Users/sherry/Desktop/文件夹/text/dict");
                strcat(dircha, "/");
                strcat(dircha, ptr->d_name);
                find_doc2(dircha,str);
                //printf("d_name: %s\n",ptr->d_name);
                continue;
            }
            if (*ret == '.' && *(ret+1) && (*(ret+1) != '.') )
            {
                printf("r_name: %s\n",ptr->d_name);
                //printf("d_name: %s\n",ptr->d_name);
            }
        }
        return;
    }
    //".txt"
    while((ptr = readdir(dir)) != NULL) ///read the list of this dir
    {
        ret = strchr(ptr->d_name,ch1);
        if (ret==NULL)
        {
            char dircha[100];
            //char *dir2;
            strcpy(dircha,"/Users/sherry/Desktop/文件夹/text/dict");
            strcat(dircha, "/");
            strcat(dircha, ptr->d_name);
            find_doc2(dircha,str);
            continue;
        }
        if (!strcmp(ret, retmain))
        {
            printf("r_name: %s\n",ptr->d_name);
            //printf("d_name: %s\n",ptr->d_name);
        }
    }
    return;
    closedir(dir);
    printf("hello");
}

//关于文件夹的寻找 不需要 部分结构没有删除
void find_doc3()
{
    DIR    *dir;
    struct    dirent    *ptr;
    dir = opendir("/Users/sherry/Desktop/文件夹/text/dict"); ///open the dir
    const char str[] = "*.*";
    const char ch1 = '.';
    char *retmain;
    char *ret;
    retmain = strchr(str, ch1);
    if (!strcmp(retmain,".*"))
    {
        while((ptr = readdir(dir)) != NULL) ///read the list of this dir
        {
            ret = strchr(ptr->d_name,ch1);
            if (ret==NULL)
            {
                printf("d_name: %s\n",ptr->d_name);
            }
        }
        return;
    }
}

//复杂状况下的文件夹遍历

void find_doc4(char *che)
{
    DIR    *dir;
    struct    dirent    *ptr;
    dir = opendir(che); ///open the dir
    const char str[] = "*.*";
    const char ch1 = '.';
    char *retmain;
    char *ret;
    retmain = strchr(str, ch1);
    if (!strcmp(retmain,".*"))
    {
        while((ptr = readdir(dir)) != NULL) ///read the list of this dir
        {
            ret = strchr(ptr->d_name,ch1);
            if (ret==NULL)
            {
                printf("d_name: %s\n",ptr->d_name);
            }
        }
        return;
    }
}
//在默认路径下寻找是否有该文件
int find_doc5(char *che,char *doc)
{
    DIR    *dir;
    struct    dirent    *ptr;
    dir = opendir(che); ///open the dir
    while((ptr = readdir(dir)) != NULL) ///read the list of this dir
    {
        if (!strcmp(ptr->d_name,doc))
        {
            return 1;
        }
    }
    return 0;
}
//是否有该文件
int find_doc6(char *che)
{
    DIR    *dir;
    dir = opendir(che); ///open the dir
    if (dir == NULL) return 0;
    return 1;
}
char str_front(char *str)
{
    return *str;
}
char str_rear(char *str)
{
    return *(str+strlen(str)-1);
}
char *str_cut(char *str)
{
    str = str+1;
    int len;
    len = strlen(str);
    memset(ch, '\0', sizeof(ch));
    strncat(ch,str,(len-1));
    return ch;
}

4. for_if.h

#ifndef for_if_h
#define for_if_h
#include "func.h"

//for if
//-l
//-f
//-r
//-d

//bool=1 存在该文件
//if 中是否包含 goto
//如果含有goto返回1
int goto_if(int line)
{
    for (int i = 0;i<word[line].numcount;i++)
    {
        if (!strcmp(word[line].mystr[i],"goto"))
        {
            return 1;
        }
    }
    return 0;
}
//if goto 返回需要返回的label
char * goto_if_find(int line)
{
    int flag = -1;
    for (int i = 0;i<word[line].numcount;i++)
    {
        if (!strcmp(word[line].mystr[i],"goto"))
        {
            flag = i;
            break;
        }
    }
    if (flag == -1 ) return NULL;
    return word[line].mystr[flag+1];
}
//是否看到变量
int flag_if_define(char *str)
{
    char ch2[10];
    strcpy(ch2,str);
    int i;
    i = strlen(ch2);
    if ((ch2[0] == '%') && (ch2[i-1] == '%'))
    {
        char * ch3;
        ch3 = find_charater(str);
        return char_tran(*ch3);
    }
    if (ch2[0] == '%')
    {
        int flag1;
        flag1 = char_tran(ch2[1]);
        char *ch3;
        ch3 = charater_num[flag1].contant;
        return char_tran(*ch3);
    }
    return char_tran(ch2[0]);
    return 0;
}

//if %1 == 3 goto lable
//判断两者是否相等,
//相等返回1,不相等返回0
int flag_if_define2(int line)
{
    int a;
    int b;
    a = flag_if_define(word[line].mystr[1]);
    b = flag_if_define(word[line].mystr[3]);
    if (a == b)
    {
        return 1;
    }
    return 0;
}
//为if语句量身定做的doc寻找
//只在本文件夹中寻找

//若缺省,在指定目录下寻找
int find_if_doc(int line)
{
    char ch2[50];
    strcpy(ch2,word[line].mystr[2]);
    char *ret;
    ret = strchr(ch2,'/');
    if (ret == NULL)
    {
        return find_doc5("/Users/sherry/Desktop/文件夹/text/dict", ch2);
    }
    return find_doc6(ch2);
}
void echo_if(int line,int n)
{
    char ch2[50];
    strcpy(ch2, word[line].mystr[n]);
    int len;
    len = strlen(ch2);
    if (ch2[len-1]==')') ch2[len-1] = '\0';
    printf("%s\n",ch2);
}

void func_if_exist(int line)
{
    if (find_if_doc(line)==1)
    {
        echo_if(line, 4);
        return;
    }
    else
    {
        if (word[line].numcount>5)
        {
            echo_if(line, 7);
        }
    }
    return;
}
//判断两个字符串是否相等
//暂时为不包含变量的简单版本
void func_if_char(int line)
{
    if (!strcmp(word[line].mystr[1],word[line].mystr[3]))
    {
        echo_if(line, 5);
        return;
    }
    else
    {
        if (word[line].numcount>6)
        {
            echo_if(line, 8);
        }
    }
    return;
}
//为if goto 量身打造的
int func_if_char1(int line)
{
    char *str1;
    str1 = goto_if_find(line);
    return func_goto(str1, line);
    //不涉及位置,可以直接用
}
void func_if_equal(int line)
{
    if (!strcmp(word[line].mystr[1],word[line].mystr[3]))
    {
        echo_if(line, 5);
        return;
    }
    else
    {
        if (word[line].numcount>6)
        {
            echo_if(line, 8);
        }
    }
    return;
}
void func_if_define(int line)
{
    char * ch2;
    ch2 = find_charater(word[line].mystr[2]);
    if (ch2 != NULL)
    {
        echo_if(line, 4);
        return;
    }
    else
    {
        if (word[line].numcount>6)
        {
            echo_if(line, 7);
        }
    }
    return;
}
//专门为if 设计的echo
// n 反应位置

//1、判断驱动器、文件或文件夹是否存在,用 if exist 语句;
//2、判断某两个字符串是否相等,用 if "字符串1"=="字符串2" 语句;
//3、判断某两个数值是否相等,用 if 数值1 equ 数值2 语句;
//4、判断某个变量是否已经被赋值,用 if defined str 语句;
//1、if exist d:\test.txt (echo D盘下有test.txt存在) else (echo D盘下不存在test.txt)
//2、if "abc" == "xyz" (echo 字符串abc等于字符串xyz) else (echo 字符串abc不等于字符串xyz)
//3、if 1 equ 2 (echo 1等于2) else (echo 1不等于2)
//4、if defined str (echo 变量str已经被赋值,其值为%str%) else (echo 变量str的值为空)
void func_if(int line)
{
    char str[30];
    strcpy(str, word[line].mystr[1]);
    if (!strcmp(str, "defined"))
    {
        func_if_define(line);
        return;
    }
    if (!strcmp(str, "exist"))
    {
        func_if_exist(line);
        return;
    }
    strcpy(str, word[line].mystr[2]);
    if (!strcmp(str, "equ"))
    {
        func_if_equal(line);
        return;
    }
    if (!strcmp(str, "=="))
    {
        func_if_char(line);
        return;
    }
}
//if " " goto
//if %1 == 3 goto lable
int func_if_goto(int line)
{
    char str[30];
    int flag_flag;
    //标注是否同意goto
    strcpy(str, word[line].mystr[2]);
    if (!strcmp(str, "not"))
    {
        flag_flag=flag_if_define2(line);
    }
    if (flag_flag==0)
    {
        return func_if_char1(line);
    }
    return line;
}
#endif /* for_if_h */

5. for_for.h

#ifndef for_for_h
#define for_for_h
#include "operater.h"
#include "func.h"

//for " " /d %%i in (???) do echo a;
//可以缺省
//对文件夹的寻找
void func_for_d(int line)
{
    char ch22[30];
    strcpy(ch22,word[line].mystr[1]);
    char *ch11;
    char *ch33;
    if (ch22[0] == '/')
    {
        ch11 = str_cut(word[line].mystr[4]);
        find_doc3();
    }
    else
    {
        ch33=str_cut(ch22);
        find_doc4(ch33);
    }
}
//for /d %%i in
//对文件的寻找 需要到下一级
void func_for_r(int line)
{
    char ch22[30];
    strcpy(ch22,word[line].mystr[1]);
    char *ch11;
    char *ch33;
    if (ch22[0] == '/')
    {
        ch11 = str_cut(word[line].mystr[4]);
        find_doc1(ch11);
    }
    else
    {
        ch33=str_cut(ch22);
        ch11 = str_cut(word[line].mystr[5]);
        find_doc2(ch33, ch22);
    }
}
//for %%i in (a,b,c) do echo %%i
//直接在后面跟变量
void func_for_i(int line)
{
    char  *f;
    f=word[line].mystr[2];
    f = f+2;
    char istr;
    istr = *f;
    char strspilit[30];
    strcpy(strspilit, str_cut(word[line].mystr[3]));
    if ( !strcmp(word[line].mystr[5],"echo"))
    {
        for (int i = 0;i<strlen(strspilit);i++)
        {
            if (strspilit[i]==',')
            {
                printf("\n");
                continue;
            }
            printf("%c",strspilit[i]);
        }
    }
    printf("\n");
}
//专门为 /l配置的分配函数
int tran_tria(char *str)
{
    char ch2;
    ch2 = *(str+1);
    return char_tran(ch2);
}
int tran_trib(char *str)
{
    char ch2;
    ch2 = *(str+3);
    return char_tran(ch2);
}
int tran_tric(char *str)
{
    char ch2;
    ch2 = *(str+5);
    return char_tran(ch2);
}
//for /L %%i in (1,1,5) do md d:\aa %%i
//建立文件夹
//这里使用echo
//for /l %%i in (1,1,5) do echo %%i;
void func_for_l(int line)
{
    int a,b,c;
    a = tran_tria(word[line].mystr[4]);
    b = tran_trib(word[line].mystr[4]);
    c = tran_tric(word[line].mystr[4]);
    for (int i = a;i<=c;i=i+b)
    {
        printf("%d\t",i);
    }
    printf("\n");
    return;
}
//for /f %c in (abc.txt) do @echo %c
//缺省条件下的判断
//自动按照空格判断
void func_for_f1(int line,char *doc)
{
    char buff[255];
    FILE *filein = NULL;
    filein = fopen(doc,"r");
    if (filein==NULL) return;
    fscanf(filein, "%s", buff);
    do
    {
        
        printf("%s\n",buff);
        fgets(buff,255,(FILE*)filein);
        fscanf(filein, "%s", buff);
    }while (!feof(filein));
    
    fclose(filein);
    return;
}
//

int tran_tri(char *str,int n)
{
    char ch2;
    ch2 = *(str+n);
    int i;
    i = char_tran(ch2);
    return i;
}
//for /f “skip=1 tokens=1,4 delims= ” %c in (d:\abc.txt) do @echo %c %d
//delims为分割字符
void func_for_f2(int line,char *doc)
{
    int skip;
    skip=tran_tri(word[line].mystr[3], 7);
    int token[5];
    int num;
    num = strlen(word[line].mystr[3]);
    num = num/2-3;
    for (int i = 0 ;i<num;i++)
    {
        
        token[i]=tran_tri(word[line].mystr[3], (7+2*i));
    }
    //取出 delim delim为分割方式
    char delim[2];
    char delimain[10];
    strcpy(delimain, word[line].mystr[4]);
    if (strlen(delimain)==7)
    {
        //delim = ' ';
        strcpy(delim," ");
        doc = str_cut(word[line].mystr[8]);
    }
    else{
        //delim=*(word[line].mystr[4]+7);
        char ch5;
        ch5=*(word[line].mystr[4]+7);
        strcpy(delim,ch5);
    }
    
    //验证性的代码段
    //printf("%c\n",delim);
    
    //扫描到哪个token[]
    int tokens_flag;
    //扫描到哪个部分
    int tokens_num;
    
    FILE *filein = NULL;
    char buff[664];
    count = 0;
    filein = fopen(doc,"r");
    char str_sen[60];
    do
    {
        fgets(buff, 255, (FILE*)filein);
        if (!feof(filein))
        {
            strcpy(str_sen, buff);
            del_char(str_sen, '\n');
            //第一个的token值就是1
            //从1开始方便计数
            //这里真的不好写函数所以不写了,看起来很乱,不愧是我
            //tokens_num = 0;
            //tokens_flag = 1;
            /*逐个字符的扫描,不适用
            for (int i = 0;i<strlen(str_sen);i++)
            {
                if ((token[tokens_num]==tokens_flag) && (str_sen[i] == delim))
                {
                    //如果上一个是对应的token
                    tokens_num ++; //换到下一个token[]
                    tokens_flag ++; //换到下一个token
                    if (tokens_num==num) break;
                    continue;
                }
                //在上一个不相同的情况下扫描到了下一个token
                if (str_sen[i] == delim)
                {
                    tokens_flag++;
                    //将相邻两个数字隔开
                    printf("\t");
                    continue;
                }
                //如果符合,在同一个框框内
                if (token[tokens_num]==tokens_flag)
                {
                    printf("%s",str_sen[i]);
                }
            }
             */
            char *tokenchar;
            
            /* 获取第一个子字符串 */
            tokenchar = strtok(str_sen, delim);
            tokens_num = 0;
            tokens_flag = 1;
            /* 继续获取其他的子字符串 */
            while( tokenchar != NULL ) {
                if (token[tokens_num]==tokens_flag)
                {
                    printf("%s\t",tokenchar);
                    tokens_num++;
                }
                
                tokens_flag++;
                if (tokens_num==num) break;
                tokenchar = strtok(NULL, delim);
            }
            printf("\n");
            //一行扫描结束,换行并进行下一行的扫描
                
        }
    }while (!feof(filein));
    return;
}
//判断该为f后该怎么做
//for /f %c in (abc.txt) do @echo %c
//for /f “skip=1 tokens=1,4 delims= ” %c in (abc.txt) do @echo %c %d
void func_for_f(int line)
{
    //第三个元素,判断是哪一种
    char ch3[10];
    strcpy(ch3, word[line].mystr[2]);
    //取出文件的名字
    char chr[30];
    char *ch4;
    if (ch3[0]=='%')
    {
        strcpy(chr,str_cut(word[line].mystr[4]));
        ch4 = str_cut(chr);
        func_for_f1(line, ch4);
        return;
    }
    if (ch3[0]=='"')
    {
        strcpy(chr,str_cut(word[line].mystr[7]));
        ch4 = str_cut(chr);
        func_for_f2(line, ch4);
        return;
    }
}
//执行for职能
//for " " /r %%i in (???) do echo a;
//for " " /d %%i in (???) do echo a;
//for %%i in (???) do echo a;
//for /L %%i in (1,1,5) do md d:\aa %%i
//for /f %c in (abc.txt) do @echo %c
//for /f “skip=1 tokens=1,4 delims= ” %c in (abc.txt) do @echo %c %d
void func_for(int line)
{
    char ch2[30];
    strcpy(ch2,word[line].mystr[1]);
    if (ch2[0]=='%')
    {
        //for %%i in (???) do echo a;
        func_for_i(line);
        return;
    }
    if (ch2[0] == '"')
    {
        char ch3[4];
        strcpy(ch3, word[line].mystr[2]);
        if (ch3[1]=='r')
        {
            func_for_r(line);
            return;
        }
        if (ch3[1]=='d')
        {
            func_for_d(line);
            return;
        }
        printf("Unknown type of%c\n",ch3[1]);
    }
    if (ch2[0] == '/')
    {
        if (ch2[1]=='l')
        {
            func_for_l(line);
            return;
        }
        if (ch2[1] == 'f')
        {
            func_for_f(line);
            return;
        }
        if (ch2[1] == 'd')
        {
            func_for_d(line);
            return;
        }
        if (ch2[1] == 'r')
        {
            func_for_r(line);
            return;
        }
    }
    //strcpy(ch,)
}


#endif /* for_for_h */

7.运行结果

new.bat内容
Alt
结果内容
Alt
goto 和while也可以实现

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值