课程设计的要求
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内容
结果内容
goto 和while也可以实现