C语言之简单版本银行储蓄系统4(结构体版本)

2023-11-12

1、老学长的唠叨

在上一个编的数组版本的简化银行系统的基础上改为结构体存储,为还没有学到结构体的学弟学妹们提供一个迁就的方案,现在将程序改为结构体存储了,也希望学弟学妹们有个c语言学习缓冲的时间,这个代码没有用多文件组织的目的是方便代码的拷贝运行,但有利又有弊,程序的可读性大大降低了,如果学过多文件组织的学弟学妹可也在新建项目的时候进行一个程序多文件组织这种方式。通过这个种方式可以让学弟学妹有能力编写出800行左右的接近工程要求的小项目。此外,还为进一步程序设计学习树立新的目标。

好了,还是得重复啰嗦一下关于这个程序,按照模块化程序设计要求,能够满足存款、取款、销户、挂失……功能。例如实现:

1.能够创建账户

2.能够从磁盘文件输入数据

3.能够将数据保存到磁盘文件中

4.实现提供目前账户个人信息的查询

6.实现对账户组的集中管理

所以各位学弟学妹们可以借这个低阶版的银行系统还是可以进行练手的

结构体数据项成员域如下:

 

通过结构体数组来存储结多位用户的账户信息,如下:

以此初步体会完整系统开发,综合运用已经学过的知识。以下提示中,给出了多个层次的需要,可以先保证最基本、最简单功能的实现,迭代式地完善,实现“改进意见”中的要求。  按照模块化程序设计要求,充分利用函数实现功能。下面为程序的功能界面

500

这里需要新建俩文件夹一个存放业务员姓名和密码的Worker.txt文件,一个存放用户的密码、状态、用户姓名、账号、余额的account.dat文件。如图:

Worker.txt文件存放业务员姓名和密码:如图

account.dat文件存放用户的密码、状态、用户姓名、账号、余额信息

2、问题描述

 

#include <stdio.h>
#include<stdlib.h> //itoa所需要的库函数
#include <string.h>
#include <ctype.h>
#include <conio.h>

#define topNum 2000 //系统最多容纳用户数目
int uActual;//实际人数
struct information
{
    char AccName[9];//账户名
    int password;//密码
    char name[10];//用户姓名
    double balance;//账户余额
    int state;//状态
};

struct information users[topNum];//用结构体数组存放银行所以用户

int iPWD();//业务员密码验证
void uExpotrData();//导出数据
void uImportData();//写入数据
void Work();//办理
int BankMenu();//银行界面
void Deposit();
void Withdraw();//取款
void ChangePWD();//改密
void Cancellation();//销户
void Sleep();//挂失
void Recovery();//解挂
void TransferAccount();//转账
void CreateAccount();//开户
void Qurey();//查询


void creatAccNum(int );
int createPWd(int );
int seek(char []);//账户判断
int see(char []);//账号查询
int verifyAll();
int verifyPAD(int Num);//密码验证
int inputPWD();

int main()
{
    printf("+------------------+\n");
    printf("+ 欢迎来到CSDN银行 +\n");
    printf("+------------------+\n");
    if(iPWD())//业务员密码验证
    {
        uExpotrData();//从文件导出数据
        Work();//业务办理
        uImportData();//写入数据到文件
    }
    return 0;
}

/*

功能:验证用户密码

返回值:密码正确,返回1;

        不能通过密码验证,返回0

*/
int iPWD()//密码登录
{
    int right = 0;
    int iTry = 3;
    int i ;
    char ch;
    char inputPsss[20];//输入账户密码
    char inputName[20];//输入业务员登录名称
    char sNameFile[20];//文件保存业务员登录名称名
    char sPassFile[20];//业务员登录密码
    FILE *fp;
    if((fp = fopen("Worker.txt","r"))==NULL)
    {
        printf("Cannot open file!");
        exit(0);
    }
    fscanf(fp,"%s %s",sNameFile,sPassFile);
    fclose(fp);

    do{
            i = 0;
            printf("请输入业务员用户名:");
            scanf("%s",inputName);
            printf("\n请输入登录密码:");
            while((ch=getch())!= '\r')
            {
                inputPsss[i++] = ch;
                putchar('*');
            }
            inputPsss[i] = '\0';
            fflush(stdin);
            printf("\n");
            if(strcmp(inputName,sNameFile)==0 && strcmp(inputPsss,sPassFile)==0)
            {
                right = 1;
                break;
            }
            else
            {
                iTry--;
                if(iTry > 0)
                {
                    printf("输入密码错误%d次,请重新输入\n",4-iTry);
                }
                else
                {
                    printf("密码输入已达3次,退出系统\n");
                }
            }
    }while(iTry);
    return right;
}

/*

功能:从文件中读取储户数据

*/
void uExpotrData()//导入数据
{
    int i=0;
    FILE *fp;
    if((fp = fopen("account.dat","r")) == NULL)
    {
        printf("File cannot open!\n");
        exit(0);
    }
    if(feof(fp))
    {
        uActual = 0;
    }
    else
    {
        //密码、状态、用户姓名、银行账号、余额写入
        while(fscanf(fp,"%d %d %s %s %lf",&users[i].password,&users[i].state,users[i].name,users[i].AccName,&users[i].balance) != EOF)
            i++;
        fclose(fp);
        uActual = i;
    }
}

/*

功能:将用户数据保存到文件中

*/
void uImportData()//写入数据
{
    int i=0;
    FILE *fp;
    if((fp = fopen("account.dat","w")) == NULL)
    {
        printf("File cannot open!\n");
        exit(0);
    }
    //密码、状态、用户名、账号、余额写入
    for(i=0;i<uActual;i++)
        fprintf(fp,"%d %d %s %s %lf\n",users[i].password,users[i].state,users[i].name,users[i].AccName,users[i].balance) ;
    fclose(fp);
}

/*

关于getch()的一点说明:

所在头文件:conio.h

函数用途:从控制台读取一个字符,但不显示在屏幕上

函数原型:int getch(void)

返回值:读取的字符

在不同平台,输入回车,getch()将返回不同数值,而getchar()统一返回10(即\n)

1)windows平台下ENTER键会产生两个转义字符 \r\n,因此getch返回13(\r)。

2)unix、 linux系统中ENTER键只产生 \n ,因此getch返回10(\n)。

3)MAC OS中ENTER键将产生 \r ,因此getch返回13(\r)。

为避免键盘缓存区中未读出的字符影响程序,用fflush(stdin);清除输入缓存区

*/
void Work()//办理
{
    int uChoice;
    if(uActual == 0)
    {
        printf("系统未存储用户数据,需办理开户\n");
        printf("是否开户:Y/N\n");
        if(tolower(getchar())=='y')//tolower()函数将字母转化为小写,非字母不做处理
        {
            CreateAccount();//开户
        }
        else
        {
            printf("退出系统");
            exit(0);
        }
    }
    do{
        uChoice = BankMenu();//界面菜单选择
        switch(uChoice)
        {
        case 1:
            Deposit();//存款
            break;
        case 2:
            Withdraw();//取款
            break;
        case 3:
            ChangePWD();//改密
            break;
        case 4:
            Cancellation();//销户
            break;
        case 5:
            CreateAccount();//开户
            break;
        case 6:
            Sleep();//挂失
            break;
        case 7:
            Recovery();//解挂
            break;
        case 8:
            TransferAccount();//转账
            break;
        case 9:
            Qurey();//查询
            break;
        case 0:
            printf("欢迎下次光临!\n");//退出
            break;
        default:
            printf("请输入选项中的0~9选项序号:");
            break;
        }
    }while(uChoice);
}

/*

功能:显示菜单并由业务员选择

返回值:用户选择的功能,范围0-9

*/
int BankMenu()//银行界面
{
    int Choice;//选择业务办理选项
    do
    {
        printf("\n\n");
        printf("  +---------------------------------+\n");
        printf("  +           办理业务选项          +\n");
        printf("  +---------------------------------+\n");
        printf("  +   1.存款    2.取款    3.改密    +\n");
        printf("  +                                 +\n");
        printf("  +   4.销户    5.开户    6.挂失    +\n");
        printf("  +                                 +\n");
        printf("  +   7.解挂    8.转账    9.查询    +\n");
        printf("  +                                 +\n");
        printf("  +   0.退出系统                    +\n");
        printf("  +---------------------------------+\n");
        printf("\n");
        printf("输入所需办理的业务序号:");
        scanf("%d",&Choice);
        fflush(stdin);
        if(Choice<=9&&Choice>=0)
            break;
        else
            printf("请输入1~9的选项");
    }while(1);
    return Choice;
}

/*

功能:存款

说明:需要保证账户存在,且处于正常状态

*/
void Deposit()//存款
{
    int site;//账户位置
    double uMoney;//存款金额
    if((site = verifyAll())!= -1)//身份验证
    {
            printf("请输入存款金额:");
            scanf("%lf",&uMoney);//
            users[site].balance +=uMoney;
            printf("已存款%0.2lf元\n余额为%0.2lf元\n",uMoney,users[site].balance);
    }
}

/*

功能:取款

说明:需要保证账户存在,且处于正常状态,另外,余额要足够取

*/
void Withdraw()//取款
{
    int site;
    double uMoney;
    if((site = verifyAll())!= -1)//身份验证
    {
        printf("请输入取款金额:");
        scanf("%lf",&uMoney);
        if(uMoney<users[site].balance)
        {
            users[site].balance -=uMoney;
            printf("已取款%0.2lf元\n余额为%0.2lf元\n",uMoney,users[site].balance);
        }
        else
            printf("余额不足!");
    }
}

/*

功能:改密码

*/
void ChangePWD()//改密
{
    int site;//查找位置
    if((site = verifyAll())!= -1)//账号查询,并返回位置
    {
        if(createPWd(site))
            printf("修改成功!");
        else
            printf("修改失败");
    }
    else
    {
        printf("修改失败\n");
    }

}

/*

功能:注销账户

说明:找到账户,并将其状态改为2-注销即可。

注销前应该检查余额,应该先取款再注销

*/
void Cancellation()//销户
{

    int site;//查找位置
    if((site = verifyAll())!= -1)
    {
        printf("你的账户余额为%0.2lf元\n",users[site].balance);
        printf("是否销户Y/N:");
        if(tolower(getchar())=='y')//tolower()函数将字母转化为小写,非字母不做处理
        {
            users[site].state=2;//销户
            printf("销户成功\n");
        }
        else
        {
            printf("销户失败\n");
        }
    }
    else
    {
        printf("\n失败\n");
    }
    return;
}

/*

功能:开户

说明:在进入系统时,在读入数据过程中,已经记录了用户数为N,在数组中对应下标为0~N-1

  开户时要增加一个用户,只要为下标为N的数组元素置值,并在成功之后令N++即可。

  这样做顺序增加简单,但遗留的后患是,在查询账户时,不得不用顺序查找,这在效率上是不划算的。

  改进的手段(1):开户时,根据账号,将数据插入到数组中,使按账号有序,这样做插入时麻烦,但有利于以后要频繁的查询操作

  改进的手段(2):账号由系统自动生成,保证其连续,这样在顺序增加的时候,就保证了其有序。

*/
void CreateAccount()//开户
{
    if(uActual == topNum)
    {
        printf("系统存储已达上线,不能开户");
        return;
    }
    printf("正在开户中……\n");
    printf("系统生成账号为:");
    creatAccNum(uActual);//生成账号
    printf("请输入姓名:");
    scanf("%s",users[uActual].name);//存入用户名
    if(createPWd(uActual)==1)//创建密码并校验
    {
        printf("请输入存款金额:");
        scanf("%lf",&users[uActual].balance);
        printf("您已经存入%lf元",users[uActual].balance);
        users[uActual].state=0;//写入状态代号为正常,0表示
        uActual++;
    }
    else
        {
            printf("返回系统选项\n");
        }
}

/*

功能:挂失账户

*/
void Sleep()//挂失
{
    int site;
    if((site = verifyAll())!= -1)//身份验证
    {
        if(users[site].state==0)//
        {
            users[site].state=1;
            printf("\n挂失成功\n");
        }
        else if(users[site].state==1)
            printf("\n该账已经挂失\n");
        else
            printf("\n该账户已经销户\n");
    }
}

/*

功能:解除挂失

*/
void Recovery()//解挂
{
    char Acc_u[20];//账号
    int site;//查找位置
    printf("请输入账号:");
    gets(Acc_u);//标准输入设备读字符串函数
    fflush(stdin);
    site = see(Acc_u);//账号查询,并返回位置
    if(site!= -1)
    {
        printf("账户名为:%s\n",users[site].name);
        if(verifyPAD(site))
        {
            if(users[site].state==1)//
            {
                users[site].state=0;
                printf("\n解挂成功\n");
            }
            else if(users[site].state==0)
                printf("\n该账户未挂失\n");
            else
                printf("\n该账户已经销户\n");
        }
    }

}

/*

功能:转账

说明:需要保证两个账户都存在,且处于正常状态,另外,转出账户的余额要足够

*/
void TransferAccount()//转账
{
    int site;
    int Num;
    double uMoney;
    char str[20];//存储输入账号数字
    if((site = verifyAll())!= -1)//身份验证
    {
        printf("请输入需要转入的账户:");
        gets(str);//标准输入设备读字符串函数
        fflush(stdin);
        if((Num = seek(str))!= -1)//
        {
            printf("请输入转账金额");
            scanf("%lf",&uMoney);
            if(uMoney < users[site].balance)
            {
                users[site].balance -= uMoney;
                users[Num].balance += uMoney;
                printf("转账成功\n账户余额为%lf",users[site].balance);
            }
            else
            {
                printf("余额不足");
            }
        }

    }
    return;
}

/*

功能:查询账户

说明:显示账户信息

*/
void Qurey()//查询
{
    int site;
    if((site = verifyAll( ))!= -1)//身份验证
    {
        printf("账户余额为%lf",users[site].balance);
    }
}

/*
作用:创建以CSDN字母开头的8位数账号,当数字小于4位数时候,数字左边用零位补齐
备注:这里调用了itoa():将整型值转换为字符串;它是一个非标准的C / C++语言功能;
需要的库函数#include<stdlib.h> ,还有用到#include<string.h>函数库里面的strlen统计字符数组包含的长度;
以及strrry()函数将字符串倒置。*/
void creatAccNum(int num)//根据实际人数自动生成账号
{
    int n;
    char s[20];//将num以字符形式保存
    char N[20]="CSDN";
    itoa(num,s,10); // itoa(int,char,要转换的十进制数)
    strrev(s);//数组倒置
    n=strlen(s);//长度
    while(n<4)
    {
        s[n]='0';
        n++;
    }
    s[n]='\0';
    strrev(s);
    strcat(N,s);//数字连接
    printf("%s\n",N);
    strcpy(users[num].AccName,N);//拷贝到用户账户里面
    return;
}

/*

功能:对新密码进行核对
说明:第一次有输入的密码与第二次输入的密码进行比较,如果密码相同则返回1表示设置成功,否者返回0

*/
int createPWd(int Num)//创建密码并校验
{
    int uPass1;//第一次输入要更改的密码
    int uPass2;//第二次输入要更改的密码
    printf("\n创建密码:");
    uPass1 = inputPWD();
    printf("\n请重新输入密码:");
    //fflush(stdin);
    uPass2 = inputPWD();
        if(uPass1==uPass2)
        {
            users[Num].password=uPass1;//写入密码
            printf("\n创建密码完成\n");
            return 1;
        }
        else
        {
            printf("\n密码不一致!\n");
        }
        return 0;
}
/*

功能:对账户进行身份验证
说明:分别验证账户,密码,当验证成功返回序号下标,账户验证失败返回-1

*/
int verifyAll()
{
    char str[20];//存储输入账号数字
    printf("请输入账号:");
    gets(str);//标准输入设备读字符串函数
    fflush(stdin);
    int site;//账号在结构体数组中的位置
    if((site =seek(str))!= -1)//账户验证
    {
        if(verifyPAD(site)!= -1)//密码验证
            {
                printf("\n成功\n");
            }
        else
            site = -1;
    }
    else
        printf("\n失败\n");
    return site;
}

/*

功能:对输入账户进行验证
功能:当对输入的

*/
int seek(char str[])//账户判断
{
    int judge=-1;
    int Num=0;
    if((Num = see(str))!= -1)//: 将一个串与另一个比较, 不管大小写,
    {
        if(users[Num].state==0)//
        {
            printf("姓名:%s\n",users[Num].name);
            judge = Num;//账户序号返回
        }
        else if(users[Num].state==1)
        {
            printf("该账户已经挂失\n");
        }
        else
        {
            printf("该账户已经销户");
        }
    }
    else
    {
        printf("该账户不存在");
    }
    return judge;
}

/*

功能:根据账号查询用户,返回用户的下标

入口参数:要查询用户的账号

返回值:如果该用户存在,返回该用户在数组中的下标,否则,返回一个负数(-1)

*/
int see(char str[])//账号查询
{
    int ptr;//存放strnicmp函数返回值
    int i;
    char N[]="CSDN";//账号前缀
    int digit;//长度
    int judge=-1;
    int Num = 0;//将数字字符转换为数字
    digit = strlen(str);//统计长度
    ptr = strnicmp(str,N,4);//
    if(digit == 8&&ptr == 0)
    {
        for(i=4;i<8;i++)
            if(isdigit(str[i]))//检查其参数是否为十进制数字字符
                Num = Num*10+(str[i]-'0');
    }
    else
    {
        if(digit != 8)
            printf("账号位数出错\n");
        if(ptr !=0)
            printf("账号请以CSDN开头\n");
    }
    if(strcmpi(str,users[Num].AccName)==0)//: 将一个串与另一个比较, 不管大小写,
        {
            printf("查找成功\n");
            judge = Num;
        }
    else
        printf("查找失败\n");
    return judge;
}
/*

功能:密码进行验证
功能:当输入密码,如果与原设置密码一致则返回数组下标序号,否则返回-1

*/
int verifyPAD(int Num)//密码验证
{
    int Pass_u;
    int judge=-1;
    printf("请输入密码:");
    Pass_u = inputPWD();
    if(Pass_u == users[Num].password)
        judge = Num;//返回存在的序号
    else
    {
        printf("\n密码错误\n");
    }
    return judge;
}

/*

功能:输入密码

返回值:整型的密码值

技术说明:

(1)此功能在多个模块中都要用到且功能单一,故分离出来,单独作业一个函数

(2)为了便于在输入中只显示*,接受输入时以字符形式输入,而后转为对应的整型数

(3)规定密码由不全为0的6位数字构成(当开头是'0'时,实际不足6位),一旦输入错误将重新输入

附:在实际的系统中,密码通常用字符串描述,即使只允许出现数字字符

首先要明白,从键盘输入的数据会先存到缓冲区,然后在存放到内存中。但是数据存放到内存中之后,
缓冲区的数据并没有释放。如果不给电脑一个清空缓冲区的命令就会造成输入无效的情况。所以需要用
到fflush(stdin)释放缓冲区。具体在C语言中主要表现在getchar()等从键盘单个或逐个数据读取的函数上
*/
int inputPWD()//密码创建
{
    int i;
    char ch;//接受字符型密码
    int uPass=0;//字符型密码转换为数字
    do
    {
        for(i=0;i<6;i++)
        {
            ch=getch();
            printf("*");
            if(isdigit(ch))//检查输入是否为十进制数字字符
                uPass=uPass*10+(ch - '0');
            else
            {
                uPass=0;
                break;
            }
        }
        fflush(stdin);
        if(uPass == 0)
        {
            printf("\n");
            printf("密码仅能够为数字\n");
            printf("请重新输入密码\n\n");
        }
        else
        {
            break;
        }
    }while(1);

    return uPass;
}

 

输出结果

1.登录

 

2.开户

 

3.存款

4……(省略)

心得体会

在编写程序的时候,学弟学妹们可以用来练练手,老学长在敲代码时候可能多多少少有错哦,当然如果你发现有什么错误的地方或者编写的不合理的地方,还得多多指正,一起进步嘛。这个简化版银行系统从精简版本、函数版本、数值版本、到现在的结构体版本、代码量也开始再增加。接下来可能就是最终版本,需要用到链表和MySql,还是希望有同学和我这个老学长一起开心的敲代码,哈哈哈哈哈!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言之简单版本银行储蓄系统4(结构体版本) 的相关文章

  • QT定时器

    QTimer使用 添加头文件 include
  • 推荐一个很适合程序员的副业!

    推荐一个超级赞的副业就是有声书录制 从2013年到现在已经火了9年时间 可谓是源远流长 这个兴趣爱好衍生出来的副业已经承载了上百万小白从业人员 头部主播的年收入都破了百万 有声书录制的发展历程可以概括为 或许曾经混沌 但必定未来可期 判断一
  • windows核心编程-杨波-专题视频课程

    windows核心编程 422人已学习 课程介绍 SDK 软件开发工具包 Software Development Kit SDK 一般是一些被软件工程师用于为特定的软件包 软件框架 硬件平台 作业系统等创建应用软件的开发工具的集合 MFC
  • Go语言基础(一)之函数调用、传参、反射机制、类型断言与转换

    Go语言基础 一 之函数调用 传参 反射机制 1 1 函数调用 package main func myFunction a b int int int return a b a b func main myFunction 66 77 使
  • 观察者模式实践-实现winform 窗体之间传值(事件实现)

    事件本身就是观察者模式的一个实现 先总结一下事件的使用 委托类型声明 定义发布者类 并声明事件 在发布者类中定义触发事件方法 定义订阅者类 并注册事件 在订阅者类中定义事件处理方法 针对事件 Net Framework提供了一个标准模式 主

随机推荐

  • linux epoll 非阻塞,Linux epoll 非阻塞connect

    为什么需要非阻塞connect 建立当前连接与其浪费等待 不如同时做些其它有意义的工作 可以异步建立多个连接 可以借助select epoll等系统调用设置合适的连接超时 而阻塞情况下只得等待默认的超时 网络上的文章大多是使用select来
  • PostgreSQL数据库保存图片

    一 postgresql 数据库的安装和配置 主要用到的命令 安装 PostgreSQL sudo apt get update sudo apt get install postgresql postgresql client 安装完毕后
  • 匿名内部类创建线程的两种方式

    我们知道多线程的实现有两种方式 一种是继承Thread类 另一种是实现Runnable接口 然后再重写run方法 最后开启线程 我们在普通的创建线程中 显然是比较麻烦的 那么有没有一个简单的方法呢 今天给大家介绍使用匿名内部类创建线程 为什
  • js逆向系列:企名片,获取js逆向后的真实数据!

    一 进入企名片创业项目 我们需要爬取如下数据 首先 对该网页进行抓包 发现这些数据是通过post请求获得的 这是网站给我们返回的数据 为什么和网页上显示的不一样呢 分析后得出 这是经过js加密后的数据 为了防止爬虫 网页对数据进行了加密 因
  • 没有50W彩礼,该怎么办

    大家好 我是才哥 刚过完春节 作为到了已婚甚至被催婚年龄的我们也开始讨论一个自古既有的话题 彩礼 今天上午 看到朋友圈刷屏了一个B站UP主的视频 没有50W彩礼 女朋友被强行拖走 我该怎么办 看完视频只想说 https www bilibi
  • Android面经_安卓面经(25/30)之MVC、MVP、MVVM全解析

    系列专栏 安卓高频面经解析大全专栏链接 150道安卓高频面试题全解析 安卓高频面经解析大全目录详情 安卓面经 anroid面经 150道安卓常见基础面试题全解析 安卓系统Framework面经专栏 Android系统Framework面试题
  • Python 5大常用魔术方法汇总

    前言 Python 中 以双下划线 包起来的方法 统称为 魔术方法 Magic Method 魔术方法是一个类或对象中的特殊方法 和普通方法的区别在于 普通方法需要手动调用 而魔术方法是在特定时刻自动触发执行的 如果希望根据自己的程序定制自
  • 开放原子开源基金会秘书长孙文龙:要打造以开发者为本的开源服务平台

    7月28日 2022开放原子全球开源峰会在北京亦创国际会展中心隆重举行开幕式 开放原子开源基金会秘书长孙文龙发表题为 凝心聚力 共拓开源 的演讲 开源开放 应运而生 开放原子开源基金会于2020年6月正式成立 作为我国首家开源基金会 也是目
  • 第一个solidity程序

    一 示例程序 SPDX License Identifier GPL 3 0 pragma solidity gt 0 4 16 lt 0 9 0 contract SimpleStorage uint storedData functio
  • 487. 金明的预算方案

    Powered by NEFU AB IN Link 文章目录 487 金明的预算方案 题意 思路 代码 487 金明的预算方案 题意 略 思路 可以将每个主件及其附件看作一个物品组 记主件为 p 两个附件为 a b 则最多一共有4种组合
  • ftp的passive模式

    昨天调试了半天的ftp passive模式 记录一下 今天在一台测试服务器上搭建ftp 折腾了许久 主要是不了解ftp的passive模式和port模式的区别 这里记录一下 和passive模式对应的叫做port模式 也叫做standard
  • Vue进阶——Vue CLI

    Vue进阶 Vue CLI 前言 一 什么是Vue CLI 二 怎么安装Vue CLI 1 Node 版本要求 2 已安装旧版本 3 安装完成 三 Vue CLI 创建Vue项目 1 Vue ui项目创建 1 1 预设 1 2 项目功能 1
  • Realme的Login接入过程记录

    为什么80 的码农都做不了架构师 gt gt gt 1 问题的提出 近期要使用Realme作为第三方接入 因为研究了一下Realme的请求过程 Request 和响应 Response 其中包含了一些加密和解密的方式 我们接下来分别从Req
  • 【Qt教程】1.9 - Qt5菜单栏、工具栏、状态栏、核心窗口、浮动窗口、QMainWindow

    1 窗口应用布局样式及组成 PC端软件 最基本的一个窗口应用布局样式 如下 大体可分为菜单栏 工具栏 状态栏 核心窗口 浮动窗口 使用时按需相互组合 2 Qt中调用这些控件 1 新建一个工程 使用QMainWindow类 2 例程源码 具体
  • Spring Security跨域问题解决

    前文介绍了 Spring 处理跨域问题的三种方案 现在来看看 Spring Security 的跨域问题解决方案 共有三种方案 摘自 深入浅出Spring Security 在实际项目使用中 推荐使用第三种方案 11 3 3 专业解决方案
  • 压缩感知及应用 源代码_【DMD应用】基于压缩感知超分辨鬼成像

    概述 分辨率是成像系统的一个重要参数 获得高分辨率图像一直是鬼成像系统的一个目标 本文提出了以成 像系统点扩散函数作为先验知识 基于稀疏测量的超分辨压缩感知鬼成像重建模型 搭建了一套计算鬼成像 实验装置 用于验证该模型对于提高鬼成像系统分辨
  • sql server登录名、服务器角色、数据库用户、数据库角色、架构区别联系

    1 一个数据库用户可以对应多个架构 架构是表容器 架构里面包含的是数据库表 2 一个数据库角色有可能涉及多个架构 数据库角色对应的是权限 3 一个用户对应一个数据库角色 4 登录名与数据库用户在服务器级别是一对多的 在数据库级别是一对一的
  • Java语言写一个简单的学生信息管理系统,通过JDBC连接数据库对学生信息进行增删改查,采用三层思想和DBUtils第三方框架。

    我把源代码和sql文件放GitHub上了 你们可以自行下载 https github com fenglily1 student 有问题可以留言或私信 我看到就会回 进阶版加上页面的管理系统在这篇 https blog csdn net w
  • linux汇编编译器:GAS和NASM的比较

    GAS即GNU AS汇编编译器 其属于AT T风格 我们常用的GNU的产品还有GCC G NASM是Linux平台下常用的汇编编译器 是intel风格的汇编编译器 MASM是Windows平台下的汇编编译器 也使用Intel风格 我们学80
  • C语言之简单版本银行储蓄系统4(结构体版本)

    1 老学长的唠叨 在上一个编的数组版本的简化银行系统的基础上改为结构体存储 为还没有学到结构体的学弟学妹们提供一个迁就的方案 现在将程序改为结构体存储了 也希望学弟学妹们有个c语言学习缓冲的时间 这个代码没有用多文件组织的目的是方便代码的拷