/*****************************************************
copyright (C), 2014-2015, Lighting Studio. Co., Ltd.
File name:
Author:Jerey_Jobs Version:0.1 Date:
Description:
Funcion List:
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
void get_name(char*);
void get_num(char*,int);
void get_address(char*);
char get_check(char*);
struct node
{
char name[20];
char hometel[9];
char phone[12];
char address[100];
struct node * next;
};
typedef struct node Node;
typedef struct node * Link;
void welcome()
{
printf(" =============================================================================\n");
printf("| |\n");
printf("| 通讯录 |\n");
printf("| |\n");
printf(" =============================================================================\n");
printf("| |\n");
printf("| 1 显示通讯录 2 添加联系人信息 |\n");
printf("| 3 删除联系人信息 4 查找联系人信息 |\n");
printf("| 5 修改联系人信息 6 退出 |\n");
printf("| |\n");
printf(" =============================================================================\n");
printf("\n");
printf("请输入操作对应的数字:");
}
void create_node(Link *new_node)
{
int count = 10;
do
{
*new_node = (Link)malloc(sizeof(Node));
count--;
}while(!is_malloc_ok(*new_node) && count);
}
void create_link(Link *head)
{
create_node(head);
(*head)->next = NULL;
}
int is_malloc_ok(Link new_node)
{
if(new_node == NULL)
{
printf("malloc error!\n");
return 0;
}
return 1;
}
void insert_node_and_sort(Link head,Link new_node)
{
Link p = head->next;
Link q = head;
if(p == NULL)
{
new_node->next = head->next;
head->next = new_node;
}
else
{
while(p != NULL && strcmp(p->name,new_node->name) < 0)
{
q = p;
p = p->next;
}
if(p == NULL)
{
new_node->next = p;
q->next = new_node;
}
else
{
q->next = new_node;
new_node->next = p;
}
}
}
void display(Link head)
{
if(head == NULL)
{
printf("链表已经完全释放!\n");
return;
}
Link p = head->next;
if(p == NULL)
{
printf("通讯录为空!\n");
}
else
{
printf("\t联系人姓名\t座机号\t\t手机号\t\t家庭地址\n");
printf("-------------------------------------------------------------\n");
while(p != NULL)
{
printf("\t%s\t\t%s\t%s\t%s\n",p->name,p->hometel,p->phone,p->address);
p = p->next;
}
}
}
void clear_screen()
{
char str;
printf("\n已成功执行,请按回车键继续操作\n");
my_get(&str,1);
system("clear");
welcome();
}
void create_new_contact(Link head,Link *new_node)
{
char str[2];
do{
create_node(new_node);
printf("请输入新联系人的\n姓 名 :");
get_name((*new_node)->name);
// scanf("%s",(*new_node)->name);
printf("座 机 号 :");
get_num((*new_node)->hometel,9);
// scanf("%s",(*new_node)->hometel);
printf("手 机 号 :");
get_num((*new_node)->phone,12);
// scanf("%s",(*new_node)->phone);
printf("家 庭 地 址:");
// scanf("%s",(*new_node)->address);
get_address((*new_node)->address);
insert_node_and_sort(head,*new_node);
printf("\n保存成功!是否要继续输入?(Y/N):");
get_check(str);
printf("\n");
}while(strcmp(str,"Y") == 0);
}
void delete_contact(Link head)
{
char str[20];
char str1[2];
do
{
printf("请输入你想删除的联系人的姓名:");
//scanf("%s",str);
get_name(str);
//delete_node(head,str);
///
Link p = head->next;
Link q=head;
while(p != NULL && strcmp(p->name,str) != 0)
{
q = p;
p = p->next;
}
if(p == NULL)
{
printf("\n抱歉,未找到你想删除的联系人,请确认是否输入正确\n");
}
else
{
q->next = p->next;
free(p);
}
///
printf("\n是否继续删除?(Y/N):");
get_check(str1);
printf("\n");
}while(strcmp(str1,"Y") == 0);
}
void delete_node(Link head,char str[])
{
Link p = head->next;
Link q=head;
while(p != NULL && strcmp(p->name,str) != 0)
{
q = p;
p = p->next;
}
if(p == NULL)
{
printf("抱歉,未找到你想删除的联系人,请确认是否输入正确\n");
}
else
{
q->next = p->next;
free(p);
printf("删除成功!");
}
}
void find_contact(Link head)
{
char str[20];
char str1[2];
Link p = head->next;
do{
printf("请输入你想查找的联系人的姓名:");
//scanf("%s",str);
get_name(str);
while(p != NULL && strcmp(str,p->name) != 0)
{
p = p->next;
}
if(p == NULL)
{
printf("抱歉,未找到你想查找的联系人,请确认输入是否正确\n");
}
else
{
printf("\n该联系人信息:\n");
printf("姓 名 :%s\n",p->name);
printf("座 机 号 :%s\n",p->hometel);
printf("手 机 号 :%s\n",p->phone);
printf("家 庭 地 址:%s\n",p->address);
}
printf("\n是否继续查询?(Y/N):");
get_check(str1);
printf("\n");
}while(strcmp(str1,"Y") == 0);
}
void alter_contact(Link head)
{
char str[20];
char str1[50];
char str2[2];
char str3[2];
int num;
Link p =head->next;
do
{
printf("1 按姓名修改 2 按座机号修改\n请输入选项: ");
//scanf("%d",&num);
num = get_mode(str3,2);
switch(num)
{
case 1:
printf("请输入你想修改的联系人的姓名:");
//scanf("%s",str);
get_name(str);
while(p != NULL && strcmp(str,p->name) != 0)
{
p = p->next;
}
if(p == NULL)
{
printf("抱歉,未找到你想修改的联系人,请确认输入是否正确\n");
}
else
{
printf("\n该联系人信息:\n");
printf("姓 名 :%s\n",p->name);
printf("座 机 号 :%s\n",p->hometel);
printf("手 机 号 :%s\n",p->phone);
printf("家 庭 地 址:%s\n",p->address);
printf("请修改:\n");
printf("请输入联系人的\n姓 名 :");
get_name(p->name);
printf("座 机 号 :");
get_num(p->hometel,9);
printf("手 机 号 :");
get_num(p->phone,12);
printf("家 庭 地 址:");
get_address(p->address);
}
break;
case 2:
printf("请输入你想修改的联系人的座机号:");
get_num(str,9);
while(p != NULL && strcmp(str,p->hometel) != 0)
{
p = p->next;
}
if(p == NULL)
{
printf("抱歉,未找到你想修改的联系人,请确认输入是否正确\n");
}
else
{
printf("\n该联系人信息:\n");
printf("姓 名 :%s\n",p->name);
printf("座 机 号 :%s\n",p->hometel);
printf("手 机 号 :%s\n",p->phone);
printf("家 庭 地 址:%s\n",p->address);
printf("请修改:\n");
printf("请输入联系人的\n姓 名 :");
get_name(p->name);
printf("座 机 号 :");
get_num(p->hometel,9);
printf("手 机 号 :");
get_num(p->phone,12);
printf("家 庭 地 址:");
get_address(p->address);
}
break;
}
printf("\n是否继续修改?(Y/N):");
get_check(str2);
printf("\n");
}while(strcmp(str2,"Y") == 0);
}
int my_get(char str[],int length) //length为存放的最长长度
{
int i;
for(i = 0; i < length ; i++)
{
str[i] = getchar();
if(str[i] == '\n')
{
str[i] = '\0';
return i;
}
}
while(getchar() != '\n');
str[i - 1] = '\0';
return -1;
}
int check_name(char *str)
{
char *p = str;
if(*p == '\0') //不加的话,如果输入姓名直接打回车键它是会认为没有错的。
{ //因为my_get会把回车改为'\0',而姓名输入又不像数字输入一样有长度限制(就是确定的长度)
return 0;
}
while(*p != '\0')
{
if(!((*p >= 'a' && *p <= 'z') || (*p >= 'A' &&*p <= 'Z')))
{
return 0;
}
p++;
}
return 1;
}
int check_num(char *str)
{
char *p = str;
while(*p != '\0')
{
if(!(*p >= '0' && *p <= '9'))
{
return 0;
}
p++;
}
return 1;
}
int check_mode(char *str,int num)
{
if(*str >= '1' && *str <= '0'+num)
{
return 1;
}
return 0;
}
int check_check(char *str)
{
if(*str == 'Y' || *str == 'N')
{
return 1;
}
return 0;
}
void get_name(char *str)
{
while(my_get(str,20) == -1 || check_name(str) == 0)
{
if(check_name(str) == 0)
{
printf("姓名中出现除大小写以外字母,");
}
else
{
printf("姓名太长超出规定范围,");
}
printf("格式不符合要求,请重新输入:");
}
}
void get_num(char *str, int length)
{
while(my_get(str,length) != length - 1 || check_num(str) == 0)
{
if(check_num(str) == 0)
{
printf("出现非数字的字符,");
}
else
{
printf("需输入%d位的号码,", length - 1);
}
printf("格式不符合要求,请重新输入:");
}
}
void get_address(char *str)
{
while(my_get(str,100) == -1)
{
printf("地址太长超出规定范围,请重新输入:");
}
}
int get_mode(char *str,int num)
{
while(my_get(str,2) == -1 || check_mode(str,num) == 0)
{
printf("请输入1-%d之间的数字:",num);
}
return *str - '0';
}
char get_check(char *str)
{
while(my_get(str,2) == -1 || check_check(str) == 0)
{
printf("请输入Y或N:");
}
return *str;
}
int read_file(Link head,Link *new_node)
{
sqlite3 *db;
int ret, i, row, column, index;
char *sql;
char *errmsg;
char **result;
ret = sqlite3_open("AddressDatabase.db",&db);
if(ret != SQLITE_OK)
{
printf("sqlite3_open error,%s\n",sqlite3_errmsg(db));
return 0;
}
sql = "select * from AddressList";
ret = sqlite3_get_table(db,sql,&result,&row,&column,&errmsg);
if(ret != SQLITE_OK)
{
printf("sqlite3_get_table error,%s\n",errmsg);
return -1;
}
index = column;
for(i = 0; i < row; i++)
{
create_node(new_node);
strcpy((*new_node)->name,result[index++]);
strcpy((*new_node)->hometel,result[index++]);
strcpy((*new_node)->phone,result[index++]);
strcpy((*new_node)->address,result[index++]);
insert_node_and_sort(head,*new_node);
}
sqlite3_close(db);
return 1;
}
int write_file(Link head)
{
Link p = head->next;
sqlite3 *db;
int ret, i;
char *sql;
char *errmsg;
ret = sqlite3_open("AddressDatabase.db",&db);
if(ret != SQLITE_OK)
{
printf("sqlite3_open error,%s\n",sqlite3_errmsg(db));
return 0;
}
sql = "drop table AddressList;";
ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
if(ret != SQLITE_OK)
{
printf("sqlite3_exec error,%s\n",errmsg);
return 0;
}
sql = "create table AddressList(name text,hometel text,phone text,address text);";
ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
if(ret != SQLITE_OK)
{
printf("sqlite3_exec error,%s\n",errmsg);
return 0;
}
sql = (char*)malloc(sizeof(char) * 141); //如果不给它赋空间,之后用sprintf会出现段错误(我也不知道为什么
while(p != NULL)
{
sprintf(sql,"insert into AddressList values('%s','%s','%s','%s');",p->name,p->hometel,p->phone,p->address);
ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
if(ret != SQLITE_OK)
{
printf("sqlite3_exec error,%s\n",errmsg);
return 0;
}
p = p->next;
}
sqlite3_close(db);
return 1;
}
int main()
{
system("clear");
welcome();
Link head;
Link new_node;
int num;
char num_get[2];
int flag = 1;
create_link(&head);
read_file(head,&new_node);
while(flag)
{
num = get_mode(num_get,6);
switch(num)
{
case 1:
display(head);
clear_screen();
break;
case 2:
create_new_contact(head,&new_node);
clear_screen();
break;
case 3:
delete_contact(head);
clear_screen();
break;
case 4:
find_contact(head);
clear_screen();
break;
case 5:
alter_contact(head);
clear_screen();
break;
case 6:
flag = 0;
break;
}
}
write_file(head);
return 0;
}
两个问题:
1.sprintf如果存入的字符串是个指针会出段错误,除非存入一个字符数组或者指针给它先赋空间
2.执行此程序前要先自行建立一个数据库并把列都建好,每次执行此程序都会把那个数据库删掉再重新建一遍把所有数据都写入,有没有更简便的方法