c语言小项目---通讯录2.0
自从上次通讯录项目被字符串项目整的自闭了之后,用了5天时间重新整理了一下通讯录的思路,并且能够正常的使用,今天按模块把基于链表的通讯录2.0版本记录一下,供后续积累经验。
首先总结一下 通讯录2.0版的不足之处:
- 由于程序基本都写在堆区和栈区,所以当程序结束后,内存里的东西也就没了,如果继续优化的话,考虑连接数据库,或者低级一点,结束前写入.txt文本,开启程序前再从.txt文件写入
- 界面粗糙,也算是c语言程序的特性吧,不像java甚至于c++能写的界面友好一点,但是作为我在这个学习阶段的逻辑训练和代码量的积累,还是比较成功的
那么接下来就分模块讲述一下整个通讯录的思路吧,先列一下思路图
第一个,就说一下上次初次尝试写通讯录时让我很纠结的 字符串输入问题,上一次利用指针和字符数组写入,要么是报错,要么就是最后一次输入内容会把前面所有字符串内容都给覆盖掉,其实上一次也有想到过利用 getchar() 函数去自己写一个getstring()的函数,但由于当时重点放在指针上(最后是因为scanf无法给指向堆区的指针写入内容),就没有太多尝试
1.getstring()函数
char *GetString()
{
int size = ;
int count = ;
char *str = (char *)malloc(size);
char *pMark = str;
char *newstr = NULL;
char c;
while((c = getchar()) != '\n')
{
*str = c;
str++;
count++;
if(count + == size)
{
*str = '\0';
size += ;
newstr = (char *)malloc(size);
strcpy_s(newstr,size,pMark);
free(pMark);
pMark = newstr;
str = newstr + count;
}
}
*str = '\0'; return pMark;
思路:由于字符数组在程序运行后,长度是定下来的,对用户的输入长度就有很大限制,所以首先在堆区开辟第一个空间,利用Getchar()获取输入缓冲区内内容,向第一个空间内依次输入字符,并计数。利用计数给第一个空间留一个‘\0’的位置,再开辟一个同样大小的空间,将第一个空间内的字符串复制给这个空间内,然后用pMark始终指向后一个开辟的空间,str从‘\0’位置继续赋值,直到识别到‘\n’为止
第二个,在编程过程中发现利用scanf()输入时,在字符缓冲区内总是会有残留的'\n',每一次都得用getchar()去清理缓存区,一是太麻烦,二是经常会忘,干脆就封装一个函数,专门用来获取字符,而且不会受到换行符的麻烦
2.GetKey()
char GetKey()
{
char c;
char z = '!';
int flag = ;
while((c=getchar()) != '\n' || == flag) //考虑了\n在之前的情况
{
z = c;
flag = ;
}
return z;
}
思路:没有什么复杂的思路,就是把'\n'排除在外,我另外又设置了一个标记,就是因为在后面的模块写的过程当中忘记了自己封装好的函数,直接使用scanf然后后面的函数也成功的把‘\n’获取进去了(好无奈啊,这个找了很长时间的bug),所以干脆就加个标记。
第三个,也是因为自己太懒了,不想每次都添加很多信息,就写了三个随机生成序号,姓名和电话号码的函数,在前期测试的时候使用
3.GetTestMessage()
int GetId()
{
static int id = ; //使用静态变量
id++;
return id;
}
char *GetName() //随机分配姓名
{
char *pname = (char *)malloc();
int i;
for(i = ;i < ;i++)
{
pname[i] = rand()% + 'a';
}
pname[i] = '\0'; return pname;
}
char *GetTel() //随机分配电话号码
{
char *ptel = (char *)malloc();
int i;
int num = rand()%+;
switch(num)
{
case :
strcpy_s(ptel,,"");
break;
case :
strcpy_s(ptel,,"");
break;
case :
strcpy_s(ptel,,"");
break;
default:
strcpy_s(ptel,,"");
break;
}
for(i = ;i < ;i++)
{
ptel[i] = rand()% + '';
}
ptel[i] = '\0'; return ptel;
}
思路:看了很多面经经常会问到 static的作用,我这里也是最浅显的一个作用声明静态变量,全局范围内可以使用,其他的我也在深入的了解,另外为了号码伪造的更像一点,用了三个号码段吧
第四个:到这才正式进入通讯录主题功能的编写,首先是获取通讯录单个结点,我分为两个部分来写,一方面是测试数据,一方面在后面可以添加
4.GetNode()
List *GetNode() //获取测试数据
{
List *pTemp = (List *)malloc(sizeof(List));
pTemp->id = GetId();
pTemp->name = GetName();
pTemp->tel = GetTel();
pTemp->next = NULL; return pTemp;
} List *GetMyNode() //获取自我添加数据
{
List *pTemp = (List *)malloc(sizeof(List));
pTemp->id = GetId();
printf("请输入姓名: ");
pTemp->name = GetString();
printf("请输入电话: ");
pTemp->tel = GetString();
pTemp->next = NULL; return pTemp;
}
思路:典型的链表添加
第五个:想一想能不能做一个分页功能呢,当数据量大的时候利用ws来翻页,所以我分为三个模块来实现这个分页功能,第一个是获取分页信息(当前页码,总共页码数,总共信息数,一页多少信息数),第二个是遍历链表按每页多少信息数,来截分,第三个是实现利用w s键来翻页,以及能返回主界面等等功能按键
5.Page()
Page *GetPage(List *pHead,int OnePageInfo) //获取页码信息
{ Page *pPage = (Page *)malloc(sizeof(Page));
pPage->CurrentPage = ;
pPage->TotalInfo = ;
pPage->OnePageInfo = OnePageInfo;
while(pHead)
{
pPage->TotalInfo++;
pHead = pHead->next;
}
pPage->TotalPage = pPage->TotalInfo%pPage->OnePageInfo == ? pPage->TotalInfo / pPage->OnePageInfo : pPage->TotalInfo / pPage->OnePageInfo + ; //三目运算符 相当于if-else的简写 return pPage;
}
void ShowInfo(List *pHead,Page *pPage) //对结点进行截分
{
int PageBegin = (pPage->CurrentPage - ) * pPage->OnePageInfo + ;
int PageEnd = (pPage->CurrentPage) * (pPage->OnePageInfo);
int InfoNum = ;
while(pHead)
{
InfoNum++;
if(InfoNum >= PageBegin && InfoNum <= PageEnd)
printf("%d\t%s\t%s\n",pHead->id,pHead->name,pHead->tel);
pHead = pHead->next;
}
return; }
void TurnPage(List *pHead,Page *pPage) //利用按键进行翻页以及其他功能
{
char c = 's';
while()
{
switch(c)
{
case 's':
if(pPage->CurrentPage < pPage->TotalPage)
{
pPage->CurrentPage++;
ShowInfo(pHead,pPage);
ShowMenu(pPage);
}
else
{
printf("已经是最后一页了!\n");
ShowMenu(pPage);
}
break;
case 'w':
if(pPage->CurrentPage > )
{
pPage->CurrentPage--;
ShowInfo(pHead,pPage);
ShowMenu(pPage);
}
else
{
printf("已经是第一页了!\n");
ShowMenu(pPage);
}
break;
case 'e':
return;
break;
case 'c':
return;
break;
case 'd':
return;
break;
case 'y':
return;
break;
case 'u':
return;
break;
default:
printf("请输入规定的按键!\n");
break;
}
c = GetKey();
g_Key = c;
// getchar(); //清空缓冲区内的\n
}
}
思路:难点在于第一个模块中确定哪些信息是能直接获取的,哪些是间接获得的。也是心血来潮用了一个三目运算符,感觉和if-else没啥区别,可能是我太菜了,哈哈哈,第二个模块中结点截获的开始位置和终止位置的确定也是一个难点,利用已知信息来确定。第三个难点其实就是我找了很长时间bug的那个‘\n’,有兴趣的话可以把 c = GetKey(); 直接写成c = getchar()体验一下。
第六个:添加功能过于简单就不直接把模块列出来了,直接在源码中展示,画个重点,我觉得最难的部分 查询功能就要来了
6.Query()
void Query(List *pHead)
{
List *pDel;
List *newpHead = NULL;
List *newpEnd = NULL;
char Choose;
char *KeyWord = NULL;
List *pNode = NULL;
List *pMark = pHead;
while()
{
while()
{
printf("请输入查询关键字: ");
KeyWord = GetString();
printf("a.确认 其他键.重新输入\n");
Choose = GetKey();
//switch(Choose)
//{
//case 'a':
// printf("%s\n",KeyWord);
// return;
// break;
//case 'c':
// printf("请重新输入!\n");
// free(KeyWord); //堆区内存不需要的话就要及时释放
// break;
//}
if(Choose == 'a') //第二种方法
{
break;
}
else
{
free(KeyWord); //堆区内存不需要的话就要及时释放
KeyWord = NULL;
}
}
pHead = pMark;
while(pHead)
{
if(!strncmp(pHead->name,KeyWord,strlen(KeyWord)) || !strncmp(pHead->tel,KeyWord,strlen(KeyWord))) //输入的长度可以用字符串长度
{
pNode = (List *)malloc(sizeof(List)); //创建一个新的链表 用现成的接口和函数进行调用
pNode->id = pHead->id;
pNode->name = pHead->name;
pNode->tel = pHead->tel;
pNode->next = NULL;
AddNode(&newpHead,&newpEnd,pNode);
}
pHead = pHead->next;
}
Browse(newpHead);
while(newpHead) //清除之前所有的结点
{
pDel = newpHead;
newpHead = newpHead->next;
free(pDel);
pDel = NULL;
}
if('e' == g_Key || 'd' == g_Key || 'u' == g_Key)
{
return;
}
}
}
思路:我想做一个前缀模糊查询,难点在于1.多个功能按键的嵌套 2.如何加入按键 3.查询后的信息如何在遍历呢,解决如下1.我也做了尝试发现switch的话一个case里需要加很多东西,就用if-else代替了,意外发现效果还不错,2.利用已有的获取菜单里的模块 加入按键,并且设一个全局变量,能在不同模块下都有不一样的菜单 3.这个我也是思考了很久,决定重新创建一个链表,专门存查找的信息,并且为了养成好滴习惯,堆区不用的空间,立马及时的清理干净。
接下来的修改和删除功能就很简单了,总结起来就是 不要造成内存浪费,记得一级和二级指针的区别,其他的和查询就很像啦
接下来直接上源码了
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
typedef struct NODE
{
int id;
char *name;
char *tel;
struct NODE *next;
}List;
typedef struct PAGE
{
int CurrentPage; //当前页数
int TotalPage; //总页数
int TotalInfo; //总条数
int OnePageInfo; //每页多少条
}Page;
int GetId();
char *GetName();
char *GetTel();
List *GetNode();
List *GetMyNode();
void AddNode(List **ppHead,List **ppEnd,List *pNode); //添加通讯录信息
void InitInfo(List **ppHead,List **ppEnd,int n); //初始化数据
Page *GetPage(List *pHead,int OnePageInfo); //获得页码信息
void ShowInfo(List *pHead,Page *pPage); //展示当前页信息
void TurnPage(List *pHead,Page *pPage); //翻页功能
char GetKey(); //获得按键,将缓冲区内的\n给排除掉
void Browse(List *pHead); //浏览通讯录信息
void ShowMenu(Page *pPage); //页码信息显示
char *GetString(); //获取字符串(scanf()函数无法给指针赋值)
void AddMessage(List **ppHead,List **ppEnd); //添加通讯录信息功能
void Query(List *pHead); //查询功能
void DeleteInfo(List **ppHead,List **ppEnd); //删除通讯录信息功能
void DeleteNode(List **ppHead,List **ppEnd,int id); //删除结点模块
void UpDataInfo(List *pHead); //修改通讯录信息功能
int g_MenuType; //全局变量以g_开头
char g_Key; //判断是否为b
int main()
{
char c;
List *pHead = NULL;
List *pEnd = NULL;
InitInfo(&pHead,&pEnd,);
while()
{
printf("1.查看通讯录\n");
printf("2.添加信息\n");
printf("3.查询信息\n");
printf("4.删除信息\n");
printf("5.修改信息\n");
printf("q.退出\n");
c = GetKey();
switch(c)
{
case '':
g_MenuType = ;
Browse(pHead);
break;
case '':
AddMessage(&pHead,&pEnd);
break;
case '':
g_MenuType = ;
Query(pHead);
break;
case '':
g_MenuType = ;
DeleteInfo(&pHead,&pEnd);
break;
case '':
g_MenuType = ;
UpDataInfo(pHead);
break;
case 'q':
return ;
break;
}
}
return ;
}
int GetId()
{
static int id = ;
id++;
return id;
}
char *GetName() //随机分配姓名
{
char *pname = (char *)malloc();
int i;
for(i = ;i < ;i++)
{
pname[i] = rand()% + 'a';
}
pname[i] = '\0'; return pname;
}
char *GetTel() //随机分配电话号码
{
char *ptel = (char *)malloc();
int i;
int num = rand()%+;
switch(num)
{
case :
strcpy_s(ptel,,"");
break;
case :
strcpy_s(ptel,,"");
break;
case :
strcpy_s(ptel,,"");
break;
default:
strcpy_s(ptel,,"");
break;
}
for(i = ;i < ;i++)
{
ptel[i] = rand()% + '';
}
ptel[i] = '\0'; return ptel;
}
List *GetNode()
{
List *pTemp = (List *)malloc(sizeof(List));
pTemp->id = GetId();
pTemp->name = GetName();
pTemp->tel = GetTel();
pTemp->next = NULL; return pTemp;
}
List *GetMyNode()
{
List *pTemp = (List *)malloc(sizeof(List));
pTemp->id = GetId();
printf("请输入姓名: ");
pTemp->name = GetString();
printf("请输入电话: ");
pTemp->tel = GetString();
pTemp->next = NULL; return pTemp;
}
void AddNode(List **ppHead,List **ppEnd,List *pNode)
{
if(*ppHead == NULL)
{
*ppHead = pNode;
}
else
{
(*ppEnd)->next = pNode;
}
*ppEnd = pNode; return;
}
void InitInfo(List **ppHead,List **ppEnd,int n)
{
int i;
srand((unsigned int)time(NULL));
for(i = ;i < n;i++)
{
AddNode(ppHead,ppEnd,GetNode());
} }
Page *GetPage(List *pHead,int OnePageInfo)
{ Page *pPage = (Page *)malloc(sizeof(Page));
pPage->CurrentPage = ;
pPage->TotalInfo = ;
pPage->OnePageInfo = OnePageInfo;
while(pHead)
{
pPage->TotalInfo++;
pHead = pHead->next;
}
pPage->TotalPage = pPage->TotalInfo%pPage->OnePageInfo == ? pPage->TotalInfo / pPage->OnePageInfo : pPage->TotalInfo / pPage->OnePageInfo + ; //三目运算符 相当于if-else的简写 return pPage;
}
void ShowInfo(List *pHead,Page *pPage)
{
int PageBegin = (pPage->CurrentPage - ) * pPage->OnePageInfo + ;
int PageEnd = (pPage->CurrentPage) * (pPage->OnePageInfo);
int InfoNum = ;
while(pHead)
{
InfoNum++;
if(InfoNum >= PageBegin && InfoNum <= PageEnd)
printf("%d\t%s\t%s\n",pHead->id,pHead->name,pHead->tel);
pHead = pHead->next;
}
return; }
void TurnPage(List *pHead,Page *pPage)
{
char c = 's';
while()
{
switch(c)
{
case 's':
if(pPage->CurrentPage < pPage->TotalPage)
{
pPage->CurrentPage++;
ShowInfo(pHead,pPage);
ShowMenu(pPage);
}
else
{
printf("已经是最后一页了!\n");
ShowMenu(pPage);
}
break;
case 'w':
if(pPage->CurrentPage > )
{
pPage->CurrentPage--;
ShowInfo(pHead,pPage);
ShowMenu(pPage);
}
else
{
printf("已经是第一页了!\n");
ShowMenu(pPage);
}
break;
case 'e':
return;
break;
case 'c':
return;
break;
case 'd':
return;
break;
case 'y':
return;
break;
case 'u':
return;
break;
default:
printf("请输入规定的按键!\n");
break;
}
c = GetKey();
g_Key = c;
// getchar(); //清空缓冲区内的\n
}
}
char GetKey()
{
char c;
char z = '!';
int flag = ;
while((c=getchar()) != '\n' || == flag) //考虑了\n在之前的情况
{
z = c;
flag = ;
}
return z;
}
void Browse(List *pHead)
{
Page *pPage = GetPage(pHead,);
TurnPage(pHead,pPage);
}
void ShowMenu(Page *pPage)
{
switch(g_MenuType)
{
case :
printf("当前%d页 共%d页 共%d条 w上一页\ts下一页\te返回\n",pPage->CurrentPage,pPage->TotalPage,pPage->TotalInfo);
break;
case :
printf("当前%d页 共%d页 共%d条 w上一页\ts下一页\tc重新查询\te返回\n",pPage->CurrentPage,pPage->TotalPage,pPage->TotalInfo);
break;
case :
printf("当前%d页 共%d页 共%d条 w上一页\ts下一页\td删除信息\te返回\n",pPage->CurrentPage,pPage->TotalPage,pPage->TotalInfo);
break;
case :
printf("当前%d页 共%d页 共%d条 w上一页\ts下一页\tu修改信息\te返回\n",pPage->CurrentPage,pPage->TotalPage,pPage->TotalInfo);
break;
} }
char *GetString()
{
int size = ;
int count = ;
char *str = (char *)malloc(size);
char *pMark = str;
char *newstr = NULL;
char c;
while((c = getchar()) != '\n')
{
*str = c;
str++;
count++;
if(count + == size)
{
*str = '\0';
size += ;
newstr = (char *)malloc(size);
strcpy_s(newstr,size,pMark);
free(pMark);
pMark = newstr;
str = newstr + count;
}
}
*str = '\0'; return pMark;
}
void AddMessage(List **ppHead,List **ppEnd)
{
List *pNode = GetMyNode();
AddNode(ppHead,ppEnd,pNode);
}
void Query(List *pHead)
{
List *pDel;
List *newpHead = NULL;
List *newpEnd = NULL;
char Choose;
char *KeyWord = NULL;
List *pNode = NULL;
List *pMark = pHead;
while()
{
while()
{
printf("请输入查询关键字: ");
KeyWord = GetString();
printf("a.确认 其他键.重新输入\n");
Choose = GetKey();
//switch(Choose)
//{
//case 'a':
// printf("%s\n",KeyWord);
// return;
// break;
//case 'c':
// printf("请重新输入!\n");
// free(KeyWord); //堆区内存不需要的话就要及时释放
// break;
//} //第一种方法 用switch去选择按键
if(Choose == 'a') //第二种方法
{
break;
}
else
{
free(KeyWord); //堆区内存不需要的话就要及时释放
KeyWord = NULL;
}
}
pHead = pMark;
while(pHead)
{
if(!strncmp(pHead->name,KeyWord,strlen(KeyWord)) || !strncmp(pHead->tel,KeyWord,strlen(KeyWord))) //输入的长度可以用字符串长度
{
pNode = (List *)malloc(sizeof(List)); //创建一个新的链表 用现成的接口和函数进行调用
pNode->id = pHead->id;
pNode->name = pHead->name;
pNode->tel = pHead->tel;
pNode->next = NULL;
AddNode(&newpHead,&newpEnd,pNode);
}
pHead = pHead->next;
}
Browse(newpHead);
while(newpHead) //清除之前所有的结点
{
pDel = newpHead;
newpHead = newpHead->next;
free(pDel);
pDel = NULL;
}
if('e' == g_Key || 'd' == g_Key || 'u' == g_Key)
{
return;
}
}
}
void DeleteNode(List **ppHead,List **ppEnd,int id)
{
List *pDel = NULL;
List *pMov = *ppHead;
if((*ppHead)->id == id)
{
pDel = *ppHead;
*ppHead = (*ppHead)->next;
free(pDel->name);
free(pDel->tel);
free(pDel);
pDel = NULL;
printf("删除成功!\n");
return;
}
if(pMov->next)
{
if(pMov->next->id == id)
{
if(pMov->next == *ppEnd)
{
pDel = *ppEnd;
*ppEnd = pMov;
(*ppEnd)->next = NULL;
}
else
{
pDel = pMov->next;
pMov->next = pMov->next->next;
}
free(pDel->name);
free(pDel->tel);
free(pDel);
pDel = NULL;
printf("删除成功!\n");
return;
}
pMov = pMov->next;
}
}
void DeleteInfo(List **ppHead,List **ppEnd)
{
int i;
while()
{
Query(*ppHead);
if('e'==g_Key)
{
break;
}
printf("请输入要删除的编号: ");
scanf("%d",&i);
DeleteNode(ppHead,ppEnd,i);
printf("y.继续删除 其他键返回\n");
if(GetKey() != 'y')
{
break;
}
}
}
void UpDataInfo(List *pHead)
{
char *str = NULL;
int id;
while()
{
Query(pHead);
if('e'==g_Key)
{
break;
}
printf("请输入修改的编号: ");
scanf("%d",&id); //用getchar()清除缓冲区内信息
getchar();
while(pHead)
{
if(pHead->id == id)
{
printf("请修改姓名: ");
str = GetString();
if(strlen(str) > )
{
free(pHead->name);
pHead->name = str;
}
printf("请修改电话号: ");
str = GetString();
if(strlen(str) > )
{
free(pHead->tel);
pHead->tel = str;
}
return;
}
pHead = pHead->next;
}
}
}
2019-04-28 23:37:16 编程小菜鸡自我反省,大佬勿喷,谢谢!!!
c语言小项目---通讯录2.0的更多相关文章
- [IT学习]Python 小项目 通讯录 思路
建立一个通讯录查询软件,暂时只支持按姓名检索.出发点:无需登录企业门户,即可检索.要注意保护员工手机号,除非他自己同意显示. 欢迎您访问www.cnblogs.com/viphhs.转载请联系作者授权 ...
- C语言小项目-基于TCP协议和SOCKET编程的网络通信系统
1.1 功能结构图 网络通信系统一共由4个模块组成,分别是点对点客户端.点对点服务端.服务器中转服务端.服务器中转客户端.这4个模块是成对使用的,点对点客户端和点对点服务端一起使用,服务器中转服务 ...
- c语言小项目-使用mysql数据库的图书管理系统
VS2013通过MySQL方式连接到MySQL MySQL官网上C++的API有两个.一个是很成熟的mysql++,另一个是MySQL Connector/C++,近两年才出的,模仿JDBC做的,封装 ...
- C语言小项目-火车票订票系统
list.h #ifndef __LIST_H__ #define __LIST_H__ #include "stdafx.h" #include <stdio.h> ...
- 小项目特供 贪吃蛇游戏(基于C语言)
C语言写贪吃蛇本来是打算去年暑假写的,结果因为ACM集训给耽搁了,因此借寒假的两天功夫写了这个贪吃蛇小项目,顺带把C语言重温了一次. 是发表博客的前一天开始写的,一共写了三个版本,第一天写了第一版,第 ...
- 微信小程序初体验,入门练手项目--通讯录,后台是阿里云服务器(一)
内容: 一.前言 二.相关概念 三.开始工作 四.启动项目起来 五.项目结构 六.设计理念 七.路由 八.部署线上后端服务 同步交流学习社区: https://www.mwcxs.top/page/4 ...
- C语言实现简单计算器小项目
昨天刚安装上devc++,半夜想着练练C语言吧 于是就看到实验楼有一个计算器的项目 之前做过一次,这次写的主要是思路 首先我们先从原理思考jia,实现简单的计算器就要具备加减乘除这些,看普通的计算器也 ...
- 【源码项目+解析】C语言/C++开发,打造一个小项目扫雷小游戏!
一直说写个几百行的小项目,于是我写了一个控制台的扫雷,没有想到精简完了代码才200行左右,不过考虑到这是我精简过后的,浓缩才是精华嘛,我就发出来大家一起学习啦,看到程序跑起来能玩,感觉还是蛮有成就感的 ...
- Java小项目--坦克大战(version1.0)
Java小项目--坦克大战<TankWar1.0> 这个小项目主要是练习j2se的基础内容和面向对象的思想.项目实现了基本的简单功能,我方一辆坦克,用上下左右键控制移动方向,按F键为发射炮 ...
随机推荐
- 腾讯云cos对象在线显示
问题 前端使用了一张cos的图片,但是无法显示图片,使用的是cdn的加速域名地址. 对比:使用服务器的直接域名是可以显示的. 两者地址直接访问时,一者在线显示,一者直接下载到本地. 原因: 使用默认提 ...
- 嵌入式C语言预处理使用
#include 包含头文件 #define 宏 #define 宏名 (宏体) //不进行语法检查 #define ABC(x) (5+(x)) //宏函数 #define #else ...
- python之format函数
自python2.6开始,新增了一种格式化字符串的函数str.format(),可谓威力十足.那么,他跟之前的%型格式化字符串相比,有什么优越的存在呢?让我们来揭开它羞答答的面纱. 语法 它通过{}和 ...
- 多次ajax请求数据json出错!!
问题描述: 1.对象数据存放在session中,每次从session中取数据 2.jsp初始化完毕调用ajax请求,返回的数据格式出错(返回部分数据,即丢失了部分数据) 解决方案:
- [ZZ] 用matlab绘制箭头
用matlab绘制箭头 http://npfeng900.blog.163.com/blog/static/14456108201221922944998/ 用matlab绘制箭头1 用matlab绘 ...
- Spring boot 线上部署
1.修改Spring Boot 1.添加:spring-boot-maven-plugin 插件 <build> <plugins> <plugin> <gr ...
- RN 的页面布局
从 https://blog.csdn.net/liangzelei/article/details/53965417转载 React Native布局详细指南 https://www.jiansh ...
- Web高级 HTTP报文
1. 报文结构 1.1 请求报文结构 Start-Line 单行,包括 Method + URL + HTTP Version Headers 多行,形式为 Name:Value Body 可选,主体 ...
- My Demos
Some elementary algorithms on discrete differential geometry http://www.cnblogs.com/yaoyansi/p/56350 ...
- monodepth 训练记录
2019年2月22日13:52:37 https://zhuanlan.zhihu.com/p/29968267 这里有个tensorlfow代码的阅读博客: https://zhuanlan.zhi ...