目前这个程序还处于编写阶段
目前内容基本写完了,还差文件内容没写
——2023年11月10日:今天突然回来诈尸一下,因为最近在复习链表的知识,增加了一些代码的鲁棒性,增加了删除函数**Delnote(void)**的功能,现在可以做到单独删除某个链表了,很适合大学生来学这块的知识。后面还会增加一些文件内容或者完善代码。
代码
#include <stdio.h>
#include <stdlib.h> //malloc() system("cls")
#include <string.h> //strcpy()
#include <ctype.h>
//#include <conio.h>
#define SIZE 50
#define USENAMEMAX 21
#define PASSWORDMAX 31
char* s_gets(char* st, int n);
int createuser(void);
int login(void);
void Writenote(void);
void Opennote(void);
int Delnote(void);
struct note {
char notebook[SIZE];
int quantity;
struct note* next;
};
char username[USENAMEMAX];
char password[PASSWORDMAX];
int pass_word_correct = 1; //密码正确标志位
int created = 0; //已注册标志位
int note_quantity = 0; //链表数量
struct note* head = NULL;
struct note* prev, * current;
char input[SIZE];
int main(void)
{
int choose = 0;
int choice = 1; //选择标志位
while (pass_word_correct)
{
printf("-------------------------------------\n");
printf("- 欢迎来到记事本 -\n");
printf("- 1.登录 其他.注册 -\n");
printf("-------------------------------------\n");
printf("请键入一个数字,回车确定\n");
scanf_s("%d", &choose,sizeof(choose));
if (choose == 1)
login();
else
createuser();
//system("cls"); //清屏函数
}
while (choice)
{
printf("-------------------------------------\n");
printf("- 欢迎来到记事本 -\n");
printf("- 输入选项进行操作 -\n");
printf("- 1.添加笔记 -\n");
printf("- 2.打开笔记 -\n");
printf("- 3.删除笔记 -\n");
printf("- 4.退出 -\n");
printf("- 当前笔记数量:%d -\n",note_quantity);
printf("-------------------------------------\n");
scanf_s("%d", &choice, sizeof(choice));
if (choice > 0 && choice < 5) {
switch (choice)
{
case 1:
Writenote();
break;
case 2:
Opennote();
break;
case 3:
Delnote();
break;
case 4:
choice = 0;
break;
}
}
else {
printf("没有这个选项");
}
}
puts("感谢使用");
return 0;
}
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
find = strchr(st, '\n');
if (find)
*find = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
int createuser(void)
{
extern char username[USENAMEMAX];
extern char password[PASSWORDMAX];
puts("请输入用户名(不超过20个字符)");
scanf_s("%s", username,sizeof(username));
if (username[0] == '0'){
printf("请不要以0为用户名\n");
return -1;
}
if (username[0] != '\0')
{
puts("请输入密码(不超过30个字符)");
int i = 0;
char pa = 0;
while (i < PASSWORDMAX) {
pa = getch();
if (pa == '\r') {
printf("\n");
break;
}
if ((pa == '\b') && i > 0) {
i--;
printf("\b \b");
}
else if (isprint(pa)) {
password[i] = pa;
printf("*");
i++;
}
}
//scanf_s("%s", password,sizeof(password));
if (password[0] != '\0')
{
system("cls");
puts("注册成功!");
//printf("u:%s,p:%s\n",username , password);
return 1;
getchar();
}
else
{
system("cls");
puts("未输入任何字符,创建失败!");
return 0;
}
}
else
{
system("cls");
puts("未输入任何字符,创建失败!");
return 0;
}
}
int login(void)
{
extern char username[USENAMEMAX];
extern char password[PASSWORDMAX];
char input_username[USENAMEMAX] = { '0' };
char input_password[PASSWORDMAX] = { '0' };
getchar();
puts("请输入用户名:(只输入一个0即可返回上一级)");
scanf_s("%s", input_username,sizeof(input_username));
if (input_username[0] == '0' && input_username[1] == '\0')
{
system("cls");
return 5;
}
puts("请输入密码:");
int i = 0;
char ch = 0;
while (i < PASSWORDMAX) {
ch = getch();
if (ch == '\r') {
printf("\n");
break;
}
if (ch == '\b' && i > 0) {
i--;
printf("\b \b");
}
else if (isprint(ch)) {
input_password[i] = ch;
printf("*");
i++;
}
}
//scanf_s("%s", input_password,sizeof(input_password));
getchar();
if (strcmp(username, input_username) == 0 && strcmp(password, input_password) == 0)
{
system("cls");
puts("登陆成功");
pass_word_correct = 0;
}
else
{
system("cls");
puts("用户名或密码错误");
//printf("iu:%s,ip:%s\n", input_username, input_password);
pass_word_correct = 1;
}
return 0;
}
void Writenote(void)
{
puts("输入记事本内容");
getchar();
while (s_gets(input, SIZE) != NULL && input[0] != '\0')
{
current = (struct note*)malloc(sizeof(struct note));
if (head == NULL)
head = current;
else
prev->next = current;
current->next = NULL;
strcpy_s(current->notebook, SIZE, input);
puts("时间");
scanf_s("%d", ¤t->quantity, SIZE);
note_quantity++;
while (getchar() != '\n')
continue;
puts("继续输入下一个笔记,无输入键入回车即可退出");
prev = current;
}
system("cls");
}
void Opennote(void)
{
system("cls");
if (note_quantity == 0) {
printf("当前无笔记\n");
return 0;
}
printf("笔记内容为:\n");
current = head;
while (current != NULL)
{
printf("内容: %s 时间:%d\n", current->notebook, current->quantity);
current = current->next;
}
}
int Delnote(void)
{
if (head == NULL) {
//链表为空无需处理
system("cls");
printf("笔记数量为0");
return -1;
}
int i = 1;
int delnum = 0;
printf("请输入要删除的笔记序号(0:全部删除)");
scanf_s("%d", &delnum, SIZE);
struct note* p, * del;
p = head;
if (delnum == 0) {
while (p->next != NULL) //删除链表非首结点元素
{
del = p->next;
p->next = p->next->next;
free(del);
}
free(p); //删除链表首结点元素
head = NULL;
note_quantity = 0;
system("cls");
}
else if (delnum == 1) {
head = head->next;
free(p);
note_quantity--;
return delnum;
}
else {
for (i = 1; i < delnum - 1; i++) {
p = p->next;
}
del = p->next;
p->next = p->next->next;
free(del);
note_quantity--;
}
return 0;
}
新增了隐藏输入密码功能,具体实现是在130-147行代码
函数总结
extern char *strcat(char *dest, const char *src);
在C中,函数原型存在 <string.h>头文件中,在C++中,则存在于头文件中。函数作用是将两个char类型连接。把src所指向的字符串(包括“\0”)复制到dest所指向的字符串后面(删除dest原来末尾的“\0”)。要保证dest足够长,以容纳被复制进来的src。src中原有的字符不变。返回指向dest的指针。
例如:
char d[20]=“Golden”;
char s[20]=“View”;
strcat(d,s);
printf(“%s”,d);
输出 d 为 GoldenView (中间无空格)
extern int strcmp(const char *s1,const char *s2);
用于比较两个字符串并根据比较结果返回整数。若s1=s2,则返回零;若s1<s2,则返回负数;若s1>s2,则返回正数。
char *strcpy(char *dest, const char *src);
strcpy,即string copy(字符串复制)的缩写。strcpy是一种C语言的标准库函数,strcpy把含有’\0’结束符的字符串复制到另一个地址空间,返回值的类型为char*。把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。src会整体覆盖dest中的内容。
这个是我自认为写的很好还很安全的一个输入函数。
char * s_gets(char * st,int n)
{
char * ret_val;
char * find;
ret_val = fgets(st,n,stdin);
if(ret_val)
{
find = strchr(st,'\n');
if(find)
*find='\0';
else
while(getchar()!='\n')
continue;
}
return ret_val;
}