结对项目:四则运算(C语言)
github地址:https://github.com/nilonger/arithmetic
结对伙伴:杨锐龙+黄海钊
一、项目要求
1.1 题目:实现一个自动生成小学四则运算题目的命令行程序(也可以用图像界面,具有相似功能)。
1.2 说明:
真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
自然数:0, 1, 2, …。
运算符:+, −, ×, ÷。
括号:(, )。
等号:=。
分隔符:空格(用于四则运算符和等号前后)。
算术表达式:
e = n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),
其中e, e1和e2为表达式,n为自然数或真分数。
四则运算题目:e = ,其中e为算术表达式。
1.3 项目要求
(完成) 使用 -n 参数控制生成题目的个数,例如 Myapp.exe -n 10 将生成10个题目。
(完成) 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如 Myapp.exe -r 10 将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。
(完成) 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1− e2的子表达式,那么e1≥ e2。
(完成) 生成的题目中如果存在形如e1÷ e2的子表达式,那么其结果应是真分数。
(完成) 每道题目中出现的运算符个数不超过3个。
程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。例如,23 + 45 = 和45 + 23 = 是重复的题目,6 × 8 = 和8 × 6 = 也是重复的题目。3+(2+1)和1+2+3这两个题目是重复的,由于+是左结合的,1+2+3等价于(1+2)+3,也就是3+(1+2),也就是3+(2+1)。但是1+2+3和3+2+1是不重复的两道题,因为1+2+3等价于(1+2)+3,而3+2+1等价于(3+2)+1,它们之间不能通过有限次交换变成同一个题目。
生成的题目存入执行程序的当前目录下的Exercises.txt文件,格式如下:
四则运算题目1
四则运算题目2
……
其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。
在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:
答案1
答案2
真分数的运算如下例所示:1/6 + 1/8 = 7/24。
程序应能支持一万道题目的生成。
程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:
Myapp.exe -e .txt -a .txt 统计结果输出到文件Grade.txt,格式如下:
Correct: 5 (1, 3, 5, 7, 9)
Wrong: 5 (2, 4, 6, 8, 10)
其中“:”后面的数字5表示对/错的题目的数量,括号内的是对/错题目的编号。为简单起见,假设输入的题目都是按照顺序编号的符合规范的题目。
二、PSP表
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
100 |
200 |
· Estimate |
· 估计这个任务需要多少时间 |
60 |
70 |
Development |
开发 |
6*24*60 |
5*24*60 |
· Analysis |
· 需求分析 (包括学习新技术) |
60 |
50 |
· Design Spec |
· 生成设计文档 |
20 |
20 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
30 |
30 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
20 |
20 |
· Design |
· 具体设计 |
100 |
150 |
· Coding |
· 具体编码 |
4*24*60 |
4*24*60 |
· Code Review |
· 代码复审 |
100 |
150 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
40 |
60 |
Reporting |
报告 |
20 |
20 |
· Test Report |
· 测试报告 |
10 |
30 |
· Size Measurement |
· 计算工作量 |
10 |
30 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
30 |
30 |
合计 |
6*24*60 |
5*24*60 |
三、解题思路
1、先实现生成式子的功能。
(1)先写好生成操作数和包含1~3个操作符的式子的四个函数,再通过一个函数一起调用,随机生成带括号的式子
(2)除号和乘号÷、×先用*、#代替
(3)C语言里面的除号和乘号÷、×不能直接从文件读出来,所以就放弃了从文件里读出来计算的想法,改为生成的时候,把式子放进数组再来计算,计算不小于0,才把数组存进文件,存进文件的时候把*、#这两个符号替换成÷、×
2、计算功能。
(1)只定义了一个分数结构体,因为想到计算的时候 整数也可以转化为分数,如2可以化为2/1
(2)定义两个栈,手撸栈的各个操作(C语言没办法),一个栈用来压入分数,一个用来压入操作符
3、比较题目文件,判断答案文件中的对错。
(1)这个可以说是取巧了一下,因为文件的生成,帮随着答案的生成,所以比较的是 标准答案文件 和 新答案文件
(2)原本是想从文件里面再读出式子拿来计算,但是写进文件后有了符号÷、×,但是那两个符号÷、×读出来会出错,因为他们不是普通字符型数据的长度。
4、主函数。
用输入参数的方式在cmd运行,很好的分开了生成式子(同时生成答案)和比较答案这两个步骤
四、设计实现过程
五、代码说明
头文件和相关结构体和栈的定义:
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
#include<string.h>
#include<io.h>
#include<math.h>
#define MINSIZE 256
#define MAXSIZE 1024
#define OK 1
#define ERROR 0 int r,n; //生成数的最大值 和 式子数量
typedef int Status; char* oneOperator();
char* creatOperator();
char* threeOperator();
char* twoOperator();
char *creatFormula(int y);
char* creatSnum();
Status Answer_Sq(char formula[],int y); typedef struct StackNode{ //分数 栈结点
int fm; //分母
int fz; //分子
struct StackNode *next;
}node1; typedef struct Stackop { //运算符 栈结点 int data;
struct Stackop *next;
}node2; typedef struct stack1 { //分数栈 node1 *top;
int length;
}StackSq1; typedef struct stack2 { //运算符栈 node2 *top;
int length;
}StackSq2;
栈的相关操作:
Status InitStack_Sq1(StackSq1 &S){ //初始化 运算数 的栈 S.top=NULL;
S.length=;
return OK;
} Status InitStack_Sq2(StackSq2 &S){ //初始化 运算符 的栈 S.top=NULL;
S.length=;
return OK;
} Status StackEmpty_Sq(StackSq2 S){ // 对 运算符 判空,若为空则返回TURE,否则返回FALSE
if(S.length==) return OK;
else return ERROR;
} Status Push_Sq1(StackSq1 &S,int fenzi,int fenmu){ //分数 进栈
node1 *p;
p=(node1 *)malloc(sizeof (node1));
p->fm=fenmu;
p->fz=fenzi;
p->next=S.top;
S.top=p;
S.length++;
return OK;
} Status Push_Sq2(StackSq2 &S,int e){ //运算符 进栈
node2 *p;
p=(node2 *)malloc(sizeof (node2));
p->data=e;
p->next=S.top;
S.top=p;
S.length++;
return OK;
} node1 Pop_Sq1(StackSq1 &S){ //记得类型是 node1
node1 A;
node1 *p=S.top;
A.fm=p->fm;
A.fz=p->fz;
S.top=p->next;
free(p);
S.length--;
return A;
} Status Pop_Sq2(StackSq2 &S){ // 运算符栈顶 出栈
int e;
node2 *p=S.top;
e=p->data;
S.top=p->next;
free(p);
S.length--;
return e;
} Status Get_Top(StackSq2 S){ //取 运算符 栈顶元素 (不出栈)
if(S.top==NULL)return ERROR;
return S.top->data;
}
生成式子的相关函数:
char* creatOperator() //生成运算符
{
srand((unsigned)time(NULL) + rand());
char* c = new char[];
int a = rand() % ;
//int a = 1;
switch (a)
{
case : strcpy(c, "+"); break;
case : strcpy(c, "-"); break;
case : strcpy(c, "*"); break;
case : strcpy(c, "#"); break;
default:
break;
}
return c;
} char* creatSnum() //生成运算数
{
srand((unsigned)time(NULL) + rand());
char* string = NULL;
char string1[MAXSIZE] = {};
string = string1;
char c[MAXSIZE] = {};
int tag = rand() % ;
int num1=,num2=;
if (tag == )
{
num1 = rand() % (r)+; //不要(size+1),保证整数不为 0
sprintf(c, "%d", num1);
strcat(string1, c); }
else
{
num1 = rand() %(r-) ; //最大为 m-2,方便后面算法 if (num1 != )
{
sprintf(c, "%d", num1);
strcat(string1, c);
strcat(string1, "/");
}
while (num2 == || num2 <= num1)
{
num2 = rand() % r; //最大为 m-1
}
sprintf(c, "%d", num2);
strcat(string1, c); }
return string;
} char* oneOperator() //一个操作符的式子
{
srand((unsigned)time(NULL) + rand());
char string[MINSIZE] = {};
char* posture = string;
char c[MINSIZE] = {};
strcpy(c, creatSnum());
strcat(string, c); strcpy(c,creatOperator());
strcat(string, c);
//printf("%s\n", string); strcpy(c, creatSnum());
strcat(string, c);
//printf("%s\n", string);
return posture;
} char* twoOperator() //两个操作符得式子
{
srand((unsigned)time(NULL) + rand());
int flag = ;
int tag=;
char string[] = {};
char* posture = string;
char c[MAXSIZE] = {}; flag = rand() % ;
if (flag == )
{
strcpy(c, "(");
strcat(string, c);
tag = ;
} strcpy(c, creatSnum());
strcat(string, c); strcpy(c,creatOperator());
strcat(string, c); strcpy(c, creatSnum());
strcat(string, c); flag = rand() % ;
if (flag == )
{
if (tag == )
{
strcpy(c, ")");
strcat(string, c);
}
tag = ;
} strcpy(c,creatOperator());
strcat(string, c); strcpy(c, creatSnum());
strcat(string, c); if (tag == )
{
strcpy(c, ")");
strcat(string, c);
} //printf("%s\n", string);
return posture;
} char* threeOperator() //三个操作符得式子
{
srand((unsigned)time(NULL) + rand());
char string[] = {};
char* posture = string;
char c[MAXSIZE] = {}; strcpy(c, creatSnum());
strcat(string, c); strcpy(c,creatOperator());
strcat(string, c); strcpy(c, creatSnum());
strcat(string, c); strcpy(c,creatOperator());
strcat(string, c); strcpy(c, creatSnum());
strcat(string, c); strcpy(c,creatOperator());
strcat(string, c); strcpy(c, creatSnum());
strcat(string, c); return posture;
} char pan[]={"-1"};
char *mp=pan;
char duan[]={""};
char *np=duan; char *creatFormula(int y) //生成式子
{
srand((unsigned)time(NULL) + rand());
// char op[3];
char string[MAXSIZE] = {};
char* posture = string;
int a = rand() % ; //生成的随机数,即运算符个数
//printf("%d\n", a); FILE *fp;
fp=fopen("test.txt","a");
int i=; char divi[]={"÷"}; //用于后面存进文件
char mult[]={"×"}; switch (a)
{
case :strcpy(string, oneOperator());
// printf("%s\n",posture); //和文件作比较
break; case :strcpy(string, twoOperator());
// printf("%s\n",posture);
break; case :strcpy(string, threeOperator());
// printf("%s\n",posture);
break; default:break;
}
if(Answer_Sq(posture,y)<) //计算的时候用 数组 算,打印则要转化一下
{
fclose(fp);
return mp; // 因为是 char 型函数,不能直接返回-1
}
else {
// fprintf(fp,"%d.%s = \n",y,posture);
fprintf(fp,"%d.",y);
while(string[i]!='\0')
{
if(string[i]=='#')
{
fprintf(fp,"%s",divi);
i++;
continue;
}
else if(string[i]=='*')
{
fprintf(fp,"%s",mult);
i++;
continue;
}
fprintf(fp,"%c",string[i]);
i++;
}
fprintf(fp,"=%c",'\n');
fclose(fp);
return np;
}
// fclose(fp);
// return posture; }
优先级判断,中间值计算,化简,生成答案文件等函数:
int Priority(char op) //判断操作符优先级
{
switch (op)
{
case '(':
return ;
case '/':
return ;
case '*':
case '#': //除号
return ;
case '+':
case '-':
return ;
default :
return ;
}
} int gcd(int x,int y)//辗转相除法 ,两整数的最大公约数
{
if(y==) return x;
return gcd(y,x%y);
} node1 CalculatorSq(node1 a,node1 b,int c){ // 两个数的计算 node1 d;
switch(c)
{
case'+':
d.fz=b.fz*a.fm + b.fm*a.fz;
d.fm=a.fm*b.fm;
break;
case'-':
d.fz=b.fz*a.fm - b.fm*a.fz;
d.fm=a.fm*b.fm;
break;
case'*':
d.fz=b.fz*a.fz;
d.fm=a.fm*b.fm;
break;
case'#':
case'/':
d.fz=b.fz*a.fm;
d.fm=b.fm*a.fz;
break; default:break;
}
return d;
} void Simpli_Fenshu(int z,int m,char strings[]) { //分数化简(将原始分数化为 真分数、带分数、整数)
int a,b,c;
char h[]={}; if(z%m==)
{
a=z/m;
itoa(a,strings,); //把 a转化为字符,存在strings[]中
// printf("%s\n",strings); //可以直接在 exe窗口 看答案
}
else if(z>m)
{
a=z/m;
b=z-a*m;
c=gcd(b,m); //求新的分子分母的 最大公因数
itoa(a,strings,);
strcat(strings,"'");
sprintf(h,"%d",b/c);
strcat(strings,h);
strcat(strings,"/");
sprintf(h,"%d",m/c);
strcat(strings,h);
// printf("%s\n",strings);
}
else if(z<m)
{
c=gcd(z,m);
a=z/c;
b=m/c;
itoa(a,strings,);
strcat(strings,"/");
itoa(b,h,);
strcat(strings,h);
// printf("%s\n",strings);
}
} Status Answer_Sq(char formula[],int y){ //计算答案 ,formula[] 为传进来的式子
StackSq1 S_num; //分数栈
StackSq2 S_ope; //运算符 栈 int i=,tmp=; node1 A,B,C; //结点
int D; //运算符 FILE *fp;
fp=fopen("answer.txt","a");
if(InitStack_Sq1(S_num)!=OK || InitStack_Sq2(S_ope)!=OK)
{
printf("初始化栈失败");
exit();
} while(formula[i]!='\0' || StackEmpty_Sq(S_ope)!=OK)
{
if(formula[i]>=''&&formula[i]<='') //判断数字
{
tmp=tmp*+formula[i]-''; //后面还是数字,继续
i++;
if(formula[i]>'' || formula[i]<'') //判断 后一个 是否 字符
{
Push_Sq1(S_num,tmp,); //把整数化为 分数 进栈
tmp=; //清零,用于记录下一个 数
}
} else //运算符
{ //等级高的 栈顶是左括号',str[i]不是右括号 运算符栈为空
if((Priority(formula[i]) > Priority(Get_Top(S_ope))) || (Get_Top(S_ope)=='(' && formula[i]!=')') || (StackEmpty_Sq(S_ope)==OK))
{
Push_Sq2(S_ope,formula[i]); //运算符 进栈
i++;
continue;
} if(Get_Top(S_ope)=='(' && formula[i]==')')
{
Pop_Sq2(S_ope); //栈顶 括号 出栈,不计算
i++;
continue;
}
// 新的运算符优先级 比 运算符栈顶的 低 数字空了,运算符还没空 新的运算符是右括号
if((Priority(formula[i]) <= Priority(Get_Top(S_ope))) || (formula[i]=='\0'&&StackEmpty_Sq(S_ope)!=OK) || formula[i]==')')
{
A=Pop_Sq1(S_num); //出栈 两个数
B=Pop_Sq1(S_num);
D=Pop_Sq2(S_ope); //出运算符 // printf("aaa%d/%d\n",A.fz,A.fm); //这些注释都是为了在exe窗口显示 计算过程
// printf("bbb%d/%d\n",B.fz,B.fm);
// printf("ccc%c\n",D); C=CalculatorSq(A,B,D); //计算中间值 (注意这里!!!) // printf("daan%d/%d\n",C.fz,C.fm); Push_Sq1(S_num,C.fz,C.fm); //中间值为正值,入栈
continue;
}
}
}
if(C.fz<)
{
fclose(fp);
return -; // 负数就返回 -1
} char daan[]={}; //用来存答案
Simpli_Fenshu(C.fz,C.fm,daan); //返回简化后的答案
fprintf(fp,"%d.%s\n",y,daan);
fclose(fp);
return ;
}
判断答案文件对错函数:
void CheckAnswer(char eflie1[],char afile2[]){
FILE *p1,*p2,*p3; p1=fopen("answer.txt","r");
p2=fopen(afile2,"r"); //传进来的文件名会变
p3=fopen("Grade.txt","w"); char answer1[]={}; //放标准答案的数组
char answer2[]={}; //放新答案文件 fgets出来的答案 int y=; //第一条式子
int c=,w=; //用于计算对和错的总题数
int correct_d[]={}; //用于储存 对的和错的题号
int wrong_d[]={}; while(fgets(answer1,,p1)!=NULL && fgets(answer2,,p2)!=NULL)
{
//不要fgets 10个字符 // printf("%s",answer1);
// printf("222%s",answer2); if(strcmp(answer1,answer2)==) //比较前n个字节的大小
{
correct_d[c++]=y;
y++;
}
else if(strcmp(answer1,answer2)!=)
{
wrong_d[w++]=y;
y++;
}
} fprintf(p3,"Correct: %d (",c);
for(int i=;i<c;i++)
{
fprintf(p3,"%d",correct_d[i]);
if(i!=c-) fprintf(p3,",");
}
fprintf(p3,")\n"); fprintf(p3,"Wrong: %d (",w);
for(int i=;i<w;i++)
{
fprintf(p3,"%d",wrong_d[i]);
if(i!=w-) fprintf(p3,",");
}
fprintf(p3,")");
fclose(p1);
fclose(p2);
fclose(p3);
}
带参数的主函数:
int main(int argc,char *argv[]){
char *line;
int y=;
if(argc<) //参数没有 4个
{
printf("你输错了或 去cmd运行!!!\n");
return ;
}
if(strcmp(argv[],"-n")== && strcmp(argv[],"-r")==)
{
n=atoi(argv[]); //字符串变为整数
r=atoi(argv[]); srand((unsigned)time(NULL)+rand()); //加个种子,随机数不同
while(n>)
{ line=creatFormula(y);
if(atoi(line)<)continue;
y++;
n--;
}
}
else if(!strcmp(argv[],"-e") && !strcmp(argv[],"-a"))
{
CheckAnswer(argv[],argv[]);
}
return ;
}
六、测试运行
1、测试生成
2、判断答案对错:
10000道题目:
七、项目小结
杨锐龙:
1、对于这次结对项目,可以说的是我是比较懒的,要不是海钊在项目发出来两三天后开始一直催着我,可能后来项目的完成会变得比较紧张,在完成项目的过程中,我们的分歧感觉很大。
2、我们没有规划好谁完成什么功能,可以说都是独立做自己的内容,然后看谁实现的功能更多更好然后决定用谁的方法,这当中也出现了不少的矛盾,因为我两都是独立写的,沟通多但是效果不好,导致有时候他问我怎么办的时候我也没有好的思路给他,或者说根本就不知道他要干嘛(这可能是这次结对项目最遗憾的地方了)。
3、虽说如此,但是也是有好的一点地方,比如在生成式子的那个阶段,他的方法用得比我更好,以至于到后来我完成自己项目的时候,还是引用了他的方法,给我带来了很大的方便,虽然沟通效果不好,但是我们也是有经常分享自己的代码成果,从中也可以get到一些不同于我的思路,比如主函数我开始是没用用参数的,在后面生成和对比答案的时候带来了一定的麻烦,但是想到了他给我的代码中出现过的带参数的主函数,也就顺便解决了出现的问题。
4、这次的结对项目可以遗憾地说是个人项目,是我们(或者我)没有get到结对项目的点上,只是多了一个伙伴相互分享代码,但是值得高兴的是我们都用自己的想法完成了项目,只是花费很多的时间。
黄海钊:
这是我第一次跟别人合作做项目,我觉得合作最大得好处就是可以共享知识,但是也带来了一个很大得问题,就是矛盾。我们有进行讨论,但是在讨论过程中意见不一,各有各的想法,导致讨论没能有太大作用。最终在共享思路的情况下各自完成代码,取其优而选着。虽说完成的不是很好,但也是经历了一个不错的过程。
结对项目:四则运算(C语言)的更多相关文章
- 结对项目——四则运算GUI项目
一.项目地址:https://git.coding.net/lvgx/wsz.git 二.PSP: PSP2.1 任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min) Plannin ...
- 结对项目-四则运算出题程序(GUI版)
目录: 一.致搭档(含项目地址) 二.PSP(planning) 三.结对编程中对接口的设计 四.计算模块接口的设计与实现过程 五.计算模块接口部分的性能改进 六.计算模块部分单元测试展示 七.计算模 ...
- 结对项目-四则运算"软件"之升级版
本次作业要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2213 github地址为:https://github.com/L ...
- 结对项目— 词频统计(语言C++)
结对对象:季天梦 博客地址:http://www.cnblogs.com/jitianmeng/ github链接:https://github.com/liuyutianlyt/EX_4.md 比例 ...
- 高级软件工程2017第3次作业——结对项目:四则运算题目生成程序(基于GUI)
Deadline:2017-10-11(周三)21:00pm (注:以下内容参考集大作业 ) 前言 想过和别人一起探索世界吗?多么希望,遇到困难时,有人能一起探讨:想要懈怠时,有人推你一把:当你专注于 ...
- 2018-2019-2 《Java程序设计》结对项目阶段总结《四则运算——整数》(二)
20175218 2018-2019-2 <Java程序设计>结对项目阶段总结<四则运算--整数> 一.需求分析 实现一个命令行程序,要求: 自动生成小学四则运算题目(加,减, ...
- 结对编程项目——四则运算vs版
结对编程项目--四则运算vs版 1)小伙伴信息: 学号:130201238 赵莹 博客地址:点我进入 小伙伴的博客 2)实现的功能: 实现带有用户界面的四则运算:将原只能在 ...
- 20175324王陈峤宇 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结
20175324王陈峤宇 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 这次的结对作业是要求我们利用栈来设计一个计算器. 自动生成四则运算 ...
- 20175229许钰玮 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结
20175229许钰玮 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 自动生成四则运算题目(加.减.乘.除). 既可以用前缀算法(波兰算法 ...
随机推荐
- 第十章 函数式接口&Stream流
10.1.函数式接口 10.1.1.概述 有且仅有一个抽象方法的接口,并且可以通过在类上标注@FunctionalInterface注解进行检测,建议自定义的函数式接口都加上这个注解 10.1.2.函 ...
- Mybatis开启二级缓存(全局缓存)的方法
Mybatis开启二级缓存的方法 开启步骤 1.在 mybatis-config.xml 的配置文件中进行显示配置,开启二级缓存(全局缓存) 2.在 Mapper.xml 文件中添加cache标签 一 ...
- jieba.lcut方法
jieba库的作用就是对中文文章进行分词,提取中文文章中的词语 cut(字符串, cut_all,HMM) 字符串是要进行分词的字符串对象 cut_all参数为真表示采用全模式分词,为假表示采用精确模 ...
- matplotlib基础汇总_01
灰度化处理就是将一幅色彩图像转化为灰度图像的过程.彩色图像分为R,G,B三个分量,分别显示出红绿蓝等各种颜色,灰度化就是使彩色的R,G,B分量相等的过程.灰度值大的像素点比较亮(像素值最大为255,为 ...
- PHP ftp_nb_fput() 函数
定义和用法 ftp_nb_fput() 函数上传本地一个已经打开的文件,并在 FTP 服务器上把它保存为一个文件.(无阻塞) 该函数返回下列值之一: FTP_FAILED(发送/获取失败) FTP_F ...
- 如何让img自动适应div容器大小
IMG样式 (横向拉伸,纵向自动匹配大小) width:100%; height:auto; (纵向拉伸,横向自动匹配大小) width:auto; height:100%; DIV样式(元素居中显示 ...
- JavaWeb基础Day17 (JSP EL表达式 jstl标签库 beanutil工具类)
JSP jsp的实质就是指在html界面中嵌入Java代码 jsp脚本 <% Java代码 %> 相当于写在service方法中. <%=java 变量或者表达式 %> ...
- Linux的VMWare中Centos7用户和用户管理三个系统文件(/etc/passwd-shadow-group解读)和批量创建用户user及用户工作环境path
Linux 用户和用户组管理 用户工作环境PATH Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统. 用 ...
- .net core编写转发服务(二) 添加服务发布订阅
源设计就单纯完成了把服务转发到特定的服务模块,一定程度上解耦了业务流程 但是我们实际开发过程中会面临服务转发后还有一些列关联的服务 举个例子 你调用了发送邮件的服务,接下来会面临扣费的服务,扣费之后会 ...
- Pytorch_第五篇_深度学习 (DeepLearning) 基础 [1]---监督学习与无监督学习
深度学习 (DeepLearning) 基础 [1]---监督学习与无监督学习 Introduce 学习了Pytorch基础之后,在利用Pytorch搭建各种神经网络模型解决问题之前,我们需要了解深度 ...