【更新】[小項目]c語言實現數據庫操作(低仿)

說明

上一篇文章裏面([小項目]c語言實現數據庫操作(低仿))的程序出現了"一些"問題,下面是對上一篇文章的程序修改。大家可以兩個程序對照着看。
更新日誌:

  1. 通過清空緩衝區解決了表名寫不進文件的問題
  2. 通過加前綴解決了庫名可表名的命名衝突(正常情況下可以重名)
  3. 修復了庫刪除後庫裏的表沒有刪除的bug
  4. 修復了表菜單功能紊亂的bug
  5. 修復了表名在庫裏但是無法識別的bug
  6. 修復了不用建庫就可以打開一個庫的bug
  7. 修復了無法寫入數據的bug
  8. 修復了delete時程序進入死循環的bug
  9. 刪除了部分多餘代碼
  10. 新增了一些註釋

仍未解決並且不準備解決的bug:

  1. 不同庫下的表命名衝突
  2. 在一次程序運行中,被選擇過的庫刪除會出錯,重新運行程序可以刪除

藉口:

  1. 應該可以通過mkdir函數來實現文件夾從而避免命名衝突
  2. 這邊建議用戶退出程序再運行就可以刪除了,(提示permission denied)原因目前我找不出來。

小結:
大部分問題結症是緩衝區和文件指針,需要注意一點的是,當文件打開的時候不可以刪除或者改名(記得關閉文件)。

全部代碼

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
FILE*fp;

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include<conio.h>
#include<ctype.h>
#define MAXLEN 10//賬號密碼最大長度
#define MAXTIME 3//登陸最大錯誤次數

FILE * fp;//數據庫文件指針
FILE * fp2;//表文件指針
FILE * fp3;//修改時用的容器

struct datas{//退一步海闊天空
    char one[20];
    char two[20];
    char three[20];
    char four[20];
};


int login();
int database_func();

int create_database();
int delete_database();
int use_database();

int table_func();

int create_table();
int delete_table();
int select_data();
int add_data();
int delete_data();
int update_data();


int main(){
    int i=0;
    while(i<MAXTIME){
        if(login()){//賬號密碼正確的時候
            while(database_func());//記得加分號,否則他會以爲while的循環體是break;實際上循環體是空語句;
            break;
        }//否則繼續循環
        i++;//記得加,否則無限循環
    }
    if(i==MAXTIME){
        system("cls");
        printf("已達到輸入次數上限,程序即將自動關閉!");
        Sleep(2000);
        return 0;
    }
    system("cls");
    printf("感謝寧的使用,再見!");
    return 0;
}


//第一層調用

int login(){//登錄,驗證密碼,正確返回1,錯誤返回0
    system("cls");
    int i = 0,flag=0;
    char ch = 0;
    char password[MAXLEN]={0},username[MAXLEN]={0};
    char true_username[]="123",true_password[]="123";
    printf("歡迎使用數據庫管理系統\n");
    printf("=========================\n");
    printf("請您先登錄\n");
    printf("=========================\n");
    printf("請輸入賬號:");
    scanf("%s",username);
    if(!strcmp(username,true_username)){//用戶名輸入正確的時候
        printf("請輸入密碼:");
        while(i<MAXLEN){
            ch = getch();//conio.h,無回顯,無緩衝區
            if(ch == '\r'){  //回車結束輸入
                /*對於不同的字符輸入函數,回車鍵產生的字符不同
                用戶按下回車鍵時,getchar() 將讀取到\n字符,
                而 getch() 將讀取到\r字符*/
                printf("\n");
                break;
            }
            if(ch=='\b'&&i>0){  //按下刪除鍵
                i--;
                printf("\b \b");
            }
            //else if 和 else 還是有區別的
            else if(isprint(ch)){  //輸入可打印字符,ctype.h
                password[i] = ch;
                printf("*");
                i++;
            }
        }
        if(!strcmp(password,true_password)){//密碼輸入正確
            return 1;
        }
        else{//密碼輸入錯誤
            printf("密碼輸入錯誤!(不妨告訴你密碼是123)\n");
            printf("寧有以下兩個選擇:\n");
            printf("=================\n");
            printf(" 1.再次嘗試登陸\n 2.退出程序\n");
            printf("=================\n");
            printf("請輸入寧的選擇:");
            scanf("%d",&flag);
            if(flag==1){
                return 0;
            }
            else{
                exit(0);//stdlib.h
            }
        }
    }
    else{//用戶名不對的時候
        printf("用戶不存在!(偷偷告訴你,用戶名只有123)\n");
        printf("寧有以下兩個選擇\n");
        printf("=================\n");
        printf(" 1.再次嘗試登陸\n 2.退出程序\n");
        printf("=================\n");
        printf("請輸入寧的選擇:");
        scanf("%d",&flag);
        if(flag==1){
            return 0;
        }
        else{
            exit(0);//stdlib.h
        }
    }
}


int database_func(){//數據庫操作菜單
    system("cls");
    //system("color 26");
    int flag=0,func=0;
    printf("功能界面\n");
    printf("============\n");
    printf(" 1.創建數據庫\n 2.刪除數據庫\n 3.選擇數據庫\n 4.退出程序\n");
    printf("============\n");
    printf("請輸入需要使用的功能:");
    scanf("%d",&func);
    switch(func){
        case 1:while(create_database());break;//創建數據庫
        case 2:while(delete_database());break;//刪除數據庫
        case 3:while(use_database());break;//打開數據庫
        case 4:exit(0);break;
    }
    system("cls");//使用功能後,判斷是否繼續使用
    printf("你有以下兩個選擇\n");
    printf("=================\n");
    printf(" 1.繼續使用\n 2.退出程序\n");
    printf("=================\n");
    printf("請輸入你的選擇:");
    scanf("%d",&flag);
    if(flag==1){//繼續使用
        return 1;
    }
    if(flag==2){//退出
        return 0;
    }
    return 0;
}


//第二層調用,父函數爲database_func

int create_database(){//創建數據庫
    system("cls");
    int flag=0;
    char db_name[10],db_url[18];
    printf("新建數據庫\n");
    printf("=================\n");
    printf("請輸入新庫的名字(len<10):");
    scanf("%s",db_name);
    strcpy(db_url,"db_");
    strcat(db_url,db_name);
    strcat(db_url,".txt");
    if((fp=fopen(db_url,"r"))==NULL){//判斷是否重複建庫
        fp=fopen(db_url,"w");
        fclose(fp);//記得!
        printf("創建成功!\n");
        Sleep(1000);
        return 0;//跳出循環
    }
    else{
        system("cls");
        printf("該庫已經被創建,或命名錯誤\n");
        printf("你有以下兩個選擇\n");
        printf("=================\n");
        printf(" 1.重新創建\n 2.取消創建數據庫\n 3.退出程序\n");
        printf("=================\n");
        printf("請輸入你的選擇:");
        scanf("%d",&flag);
        if(flag==1){
            return 1;//再次創建
        }
        if(flag==2){
            return 0;//跳出循環
        }
        if(flag==3){
            exit(0);
        }
        else{
            printf("沒有該選項!\n結束創建");
            Sleep(1000);
            return 0;
        }
    }
}


int delete_database(){//刪除數據庫
    system("cls");
    int flag=0;
    char db_name[10],db_url[18],haven[18];
    printf("刪除數據庫\n");
    printf("=================\n");
    printf("請輸入要刪除的數據庫的名字:");
    scanf("%s",db_name);
    strcpy(db_url,"db_");
    strcat(db_url,db_name);
    strcat(db_url,".txt");
    //遍歷刪除庫
    fp=fopen(db_url,"r");
    while(fscanf(fp,"%s",haven)!=EOF){//防止讀入\n用fscanf
        //其實下面的表操作用fscanf來讀入更好,但是我之前通過其他手段解決了這個問題,我就懶得改了(我當時怎麼沒想到用fscanf?
        remove(haven);
    }
    fclose(fp);//如果沒關上會出現permission Denied
    //打開過的庫會出現permission Denied??????
    if(!(remove(db_url))){//成功返回零
        printf("刪除成功!\n");
        Sleep(1000);
        return 0;//跳出循環
    }
    else{
        system("cls");
        printf("%s\n",strerror(errno));
        printf("在本次運行打開過的庫刪除會失敗,建議退出程序在運行刪除,親測有效!\n",)
        printf("你有以下兩個選擇\n");
        printf("=================\n");
        printf(" 1.再次刪除\n 2.取消刪除數據庫\n 3.退出程序\n");
        printf("=================\n");
        printf("請輸入你的選擇:");
        scanf("%d",&flag);
        if(flag==1){
            return 1;//再次創建
        }
        if(flag==2){
            return 0;//跳出循環
        }
        if(flag==3){
            exit(0);
        }
        else{
            printf("沒有該選項!\n結束刪除");
            Sleep(2000);
            return 0;
        }
    }
}


int use_database(){//打開數據庫
    system("cls");
    int flag=0;
    char db_name[10],db_url[18];
    printf("打開數據庫\n");
    printf("=================\n");
    printf("請輸入要打開的數據庫的名字:");
    scanf("%s",db_name);
    strcpy(db_url,"db_");
    strcat(db_url,db_name);
    strcat(db_url,".txt");
    if((fp=fopen(db_url,"r"))!=NULL){//判斷數據庫是否存在
        fp=fopen(db_url,"a+");
        printf("成功打開!\n");
        Sleep(1000);
        while(table_func(db_url));
        fclose(fp);//循環的過程中文件一直打開,如果不及時清空緩衝區就一直無法寫入
        return 0;//跳出循環
    }
    else{
        system("cls");
        printf("該庫已經不存在\n");
        printf("你有以下兩個選擇\n");
        printf("=================\n");
        printf(" 1.打開另一個\n 2.取消打開數據庫\n 3.退出程序\n");
        printf("=================\n");
        printf("請輸入你的選擇:");
        scanf("%d",&flag);
        if(flag==1){
            return 1;//再次創建
        }
        if(flag==2){
            return 0;//跳出循環
        }
        if(flag==3){
            exit(0);
        }
        else{
            printf("沒有該選項!\n結束創建");
            Sleep(2000);
            return 0;
        }
    }
}


//第三層調用,父函數爲use_database

int table_func(char * db_url){//表操作菜單
    system("cls");
    int flag=0,func=0;
    char db_name[13]={0};
    //有些庫名可以顯示全,有些就被閹割了一些
    strcpy(db_name,strtok(db_url,".txt"));
    printf("%s庫\n",db_name);
    printf("============\n");
    printf(" 1.創建表\n 2.刪除表\n 3.查詢信息\n 4.增加信息\n 5.刪除信息\n 6.修改信息\n 7.退出程序\n");
    printf("============\n");
    printf("請輸入需要使用的功能:");
    scanf("%d",&func);
    switch(func){
        case 1:while(create_table(db_url));break;//創建表
        case 2:while(delete_table(db_url));break;//刪除表
        case 3:while(select_data(db_url));break;//查詢數據
        case 4:while(add_data(db_url));break;//增加數據
        case 5:while(delete_data(db_url));break;//刪除數據
        case 6:while(update_data(db_url));break;//修改數據
        case 7:exit(0);break;
    }
    //使用功能後,判斷是否繼續使用
    system("cls");
    printf("你有以下兩個選擇\n");
    printf("=================\n");
    printf(" 1.繼續使用\n 2.退出庫\n 3.退出程序\n");
    printf("=================\n");
    printf("請輸入你的選擇:");
    scanf("%d",&flag);
    if(flag==1){//繼續使用
        return 1;
    }
    if(flag==2){//退出
        return 0;
    }
    if(flag==3){
        exit(0);
    }
    return 0;
}


//第四層調用,父函數爲table_func

int create_table(char *db_url){//創建表,和創建庫差不多,要把表名放入庫文件中
    system("cls");
    int flag=0,n=0,i=0;
    char tb_name[10],tb_url[15];
    fseek(fp,0,SEEK_SET);//將文件光標回到開頭,防止多次操作導致光標在文件末尾無法讀取到前面的內容
    struct datas data;
    //初始化
    strcpy(data.one,"null");
    strcpy(data.two,"null");
    strcpy(data.three,"null");
    strcpy(data.four,"null");
    printf("新建表\n");
    printf("=================\n");
    printf("請輸入新表的名字(len<10):");
    scanf("%s",tb_name);
    strcpy(tb_url,tb_name);
    strcat(tb_url,".txt");
    if((fp2=fopen(tb_url,"r"))==NULL){//判斷是否重複建表
        fp2=fopen(tb_url,"w");
        printf("請輸入新表的字段數(<=4):");
        scanf("%d",&n);
        if(n>4){
            printf("對不起,程序員太菜無法支持創建這麼多字段的表(妥協\n");
        }
        else{
            for(i=0;i<n;i++){
                printf("請輸入第%d個字段名:",i+1);
                switch(i){
                    case 0:scanf("%s",data.one);break;
                    case 1:scanf("%s",data.two);break;
                    case 2:scanf("%s",data.three);break;
                    case 3:scanf("%s",data.four);break;
                }
            }
        }
        fprintf(fp2,"%d\n",n);
        fprintf(fp2,"%22s%22s%22s%22s\n",data.one,data.two,data.three,data.four);
        fclose(fp2);
        fflush(stdin);
        fprintf(fp,"%s\n",tb_url);//把表名放進數據庫中,記得換行,文件已被上層函數打開
        fflush(fp);//清空緩衝區,使表名在
        printf("創建成功!\n");
        Sleep(1000);
        return 0;//跳出循環
    }
    else{
        system("cls");
        printf("該表已經被創建,或命名錯誤\n");
        printf("你有以下兩個選擇\n");
        printf("=================\n");
        printf(" 1.重新創建\n 2.取消創建表\n 3.退出程序\n");
        printf("=================\n");
        printf("請輸入你的選擇:");
        scanf("%d",&flag);
        if(flag==1){
            return 1;//再次創建
        }
        if(flag==2){
            return 0;//跳出循環
        }
        if(flag==3){
            exit(0);
        }
        else{
            printf("沒有該選項!\n結束創建");
            Sleep(2000);
            return 0;
        }
    }
}


int delete_table(char *db_url){
    system("cls");
    int flag=0;
    char tb_name[10],tb_url[15],haven[16];
    fseek(fp,0,SEEK_SET);//將文件光標回到開頭,防止多次操作導致光標在文件末尾無法讀取到前面的內容
    printf("刪除表\n");
    printf("=================\n");
    printf("請輸入要刪除的表的名字:");
    scanf("%s",tb_name);
    strcpy(tb_url,tb_name);
    strcat(tb_url,".txt\n");//文件裏的tb_url始終有\n跟着
    strcat(tb_name,".txt");//雖然語義不對,但是懶得加變量了
    while(fgets(haven,16,fp)!=NULL){//一行一個信息????????????????????????????????????
        if(!(strcmp(haven,tb_url))){//發現匹配表
            if(!(remove(tb_name))){//成功返回零,沒有測試過行不行
                printf("刪除成功!\n");
                Sleep(2000);
                return 0;//跳出循環
            }
            else{//刪除失敗
                system("cls");
                printf("刪除出錯\n");
                printf("你有以下兩個選擇\n");
                printf("=================\n");
                printf(" 1.重新刪除\n 2.結束刪除表\n 3.退出程序\n");
                printf("=================\n");
                printf("請輸入你的選擇:");
                scanf("%d",&flag);
                if(flag==1){
                    return 1;//再次創建
                }
                if(flag==2){
                    return 0;//跳出循環
                }
                if(flag==3){
                    exit(0);
                }
                else{
                    printf("沒有該選項!\n結束刪除");
                    return 0;
                }
            }
        }
    }
    //匹配成功的都出去了,匹配失敗纔會執行下面的語句
    system("cls");
    printf("庫裏沒有這個表");
    printf("你有以下兩個選擇\n");
    printf("=================\n");
    printf(" 1.刪除另一個表\n 2.取消刪除表操作\n 3.退出程序\n");
    printf("=================\n");
    printf("請輸入你的選擇:");
    scanf("%d",&flag);
    if(flag==1){
        return 1;//再次創建
    }
    if(flag==2){
        return 0;//跳出循環
    }
    if(flag==3){
        exit(0);
    }
    else{
        printf("沒有該選項!\n結束刪除");
        Sleep(2000);
        return 0;
    }
}


int select_data(char *db_url){
    system("cls");
    int flag=0,a;
    struct datas data;
    strcpy(data.one,"null");
    strcpy(data.two,"null");
    strcpy(data.three,"null");
    strcpy(data.four,"null");
    char tb_name[10],tb_url[15],haven[16];
    fseek(fp,0,SEEK_SET);//將文件光標回到開頭,防止多次操作導致光標在文件末尾無法讀取到前面的內容
    printf("查詢表\n");
    printf("=================\n");
    printf("請輸入要查詢的表的名字:");
    scanf("%s",tb_name);
    strcpy(tb_url,tb_name);
    strcat(tb_url,".txt\n");
    strcat(tb_name,".txt");
    while(fgets(haven,16,fp)!=NULL){//一行一個信息
        if(!strcmp(haven,tb_url)){//發現匹配表
            if((fp2=fopen(tb_name,"r"))!=NULL){//確認表沒有被刪
                fscanf(fp2,"%d\n",&a);//把字段數讀取掉
                while(fscanf(fp2,"%22s%22s%22s%22s\n",data.one,data.two,data.three,data.four)!=EOF){
                    printf("%22s%22s%22s%22s\n",data.one,data.two,data.three,data.four);
                }
                printf("查詢成功!\n");
                fclose(fp2);
                printf("輸入任意鍵繼續......");
                getch();//讀取任意鍵,達到暫停的效果
                return 0;//跳出循環
            }
            else{
                system("cls");
                printf("表可能已經被刪除\n");
                printf("你有以下兩個選擇\n");
                printf("=================\n");
                printf(" 1.重新查詢\n 2.結束查詢表\n 3.退出程序\n");
                printf("=================\n");
                printf("請輸入你的選擇:");
                scanf("%d",&flag);
                if(flag==1){
                    return 1;//再次創建
                }
                if(flag==2){
                    return 0;//跳出循環
                }
                if(flag==3){
                    exit(0);
                }
                else{
                    printf("沒有該選項!\n結束刪除");
                    return 0;
                }
            }
        }
    }
    //匹配成功的都出去了,匹配失敗纔會執行下面的語句
    system("cls");
    printf("庫裏沒有這個表");
    printf("你有以下兩個選擇\n");
    printf("=================\n");
    printf(" 1.查詢另一個表\n 2.取消查詢表操作\n 3.退出程序\n");
    printf("=================\n");
    printf("請輸入你的選擇:");
    scanf("%d",&flag);
    if(flag==1){
        return 1;//再次創建
    }
    if(flag==2){
        return 0;//跳出循環
    }
    if(flag==3){
        exit(0);
    }
    else{
        printf("沒有該選項!\n結束刪除");
        Sleep(2000);
        return 0;
    }
}


int add_data(){
    system("cls");
    int flag=0,i=0,n=0;
    struct datas data;
    //初始化結構體
    strcpy(data.one,"null");
    strcpy(data.two,"null");
    strcpy(data.three,"null");
    strcpy(data.four,"null");
    fseek(fp,0,SEEK_SET);//將文件光標回到開頭,防止多次操作導致光標在文件末尾無法讀取到前面的內容
    char tb_name[10],tb_url[15],haven[16];
    printf("增加數據\n");
    printf("=================\n");
    printf("請輸入要增加數據的表的名字:");
    scanf("%s",tb_name);
    strcpy(tb_url,tb_name);
    strcat(tb_url,".txt\n");
    strcat(tb_name,".txt");
    while(fgets(haven,16,fp)!=NULL){//一行一個信息
        if(!strcmp(haven,tb_url)){//發現匹配表
            if((fp2=fopen(tb_name,"a+"))!=NULL){
                fscanf(fp2,"%d\n",&n);
                if(n==0){//如果文件已經被刪除
                    system("cls");
                    printf("文件已被刪除\n");
                    printf("你有以下兩個選擇\n");
                    printf("=================\n");
                    printf(" 1.重新查詢\n 2.結束查詢表\n 3.退出程序\n");
                    printf("=================\n");
                    printf("請輸入你的選擇:");
                    scanf("%d",&flag);
                    if(flag==1){
                        return 1;//再次創建
                    }
                    if(flag==2){
                        return 0;//跳出循環
                    }
                    if(flag==3){
                        exit(0);
                    }
                    else{
                        printf("沒有該選項!\n結束刪除");
                        return 0;
                    }
                }
                for(i=0;i<n;i++){
                    printf("請輸入第%d列的數據:",i+1);
                    switch(i){
                        case 0:scanf("%s",data.one);break;
                        case 1:scanf("%s",data.two);break;
                        case 2:scanf("%s",data.three);break;
                        case 3:scanf("%s",data.four);break;
                    }
                }
                fseek(fp2,0,SEEK_END);//讀寫轉換的時候要重新定位光標的位置,否則fprintf會失敗返回EOF
                fprintf(fp2,"%22s%22s%22s%22s\n",data.one,data.two,data.three,data.four);
                printf("添加數據成功!\n");
                fflush(fp2);
                fclose(fp2);
                Sleep(1000);
                return 0;//跳出循環
            }
        }
    }
    //匹配成功的都出去了,匹配失敗纔會執行下面的語句
    system("cls");
    printf("庫裏沒有這個表");
    printf("你有以下兩個選擇\n");
    printf("=================\n");
    printf(" 1.查詢另一個表\n 2.取消查詢表操作\n 3.退出程序\n");
    printf("=================\n");
    printf("請輸入你的選擇:");
    scanf("%d",&flag);
    if(flag==1){
        return 1;//再次創建
    }
    if(flag==2){
        return 0;//跳出循環
    }
    if(flag==3){
        exit(0);
    }
    else{
        printf("沒有該選項!\n結束刪除");
        Sleep(2000);
        return 0;
    }
}


int delete_data(){
    system("cls");
    int flag=0,i=1,n,a;//這裏初始化i爲1
    struct datas data={0};//初始化結構體
    char tb_name[10],tb_url[15],haven[16];
    fseek(fp,0,SEEK_SET);//將文件光標回到開頭,防止多次操作導致光標在文件末尾無法讀取到前面的內容
    printf("刪除數據\n");
    printf("=================\n");
    printf("請輸入要刪除數據的表的名字:");
    scanf("%s",tb_name);
    strcpy(tb_url,tb_name);
    strcat(tb_url,".txt\n");
    strcat(tb_name,".txt");
    while(fgets(haven,16,fp)!=NULL){//一行一個信息????????????????????????????????????
        if(!strcmp(haven,tb_url)){//發現匹配表
            if((fp2=fopen(tb_name,"r"))!=NULL){//只能讀,否則數據沒了
                fscanf(fp2,"%d\n",&a);
                fp3=fopen("__temp.txt","w");//修改專用文件
                printf("請輸入要刪除的行號:");
                scanf("%d",&n);
                n=n+1;//此時光標已經到了第二行,確保第兩行不會被刪掉
                fprintf(fp3,"%d\n",a);
                while(fscanf(fp2,"%22s%22s%22s%22s\n",data.one,data.two,data.three,data.four)!=EOF){
                    if(i==n){
                        i++;//記得加否則後面都沒了
                        continue;
                    }
                    else{
                        fprintf(fp3,"%22s%22s%22s%22s\n",data.one,data.two,data.three,data.four);
                    }
                    i++;
                }
                fclose(fp2);
                remove(tb_name);//刪除舊文件
                fclose(fp3);//注意位置
                rename("__temp.txt",tb_name);
                printf("刪除數據成功!\n");
                Sleep(1000);//讀取任意鍵,達到暫停的效果
                return 0;//跳出循環
            }
            else{
                system("cls");
                printf("文件出錯\n");
                printf("你有以下兩個選擇\n");
                printf("=================\n");
                printf(" 1.重新刪除\n 2.結束刪除表\n 3.退出程序\n");
                printf("=================\n");
                printf("請輸入你的選擇:");
                scanf("%d",&flag);
                if(flag==1){
                    return 1;//再次創建
                }
                if(flag==2){
                    return 0;//跳出循環
                }
                if(flag==3){
                    exit(0);
                }
                else{
                    printf("沒有該選項!\n結束刪除");
                    return 0;
                }
            }
        }
    }
    //匹配成功的都出去了,匹配失敗纔會執行下面的語句
    system("cls");
    printf("庫裏沒有這個表");
    printf("你有以下兩個選擇\n");
    printf("=================\n");
    printf(" 1.刪除另一個表的數據\n 2.取消刪除表操作\n 3.退出程序\n");
    printf("=================\n");
    printf("請輸入你的選擇:");
    scanf("%d",&flag);
    if(flag==1){
        return 1;//再次創建
    }
    if(flag==2){
        return 0;//跳出循環
    }
    if(flag==3){
        exit(0);
    }
    else{
        printf("沒有該選項!\n結束刪除");
        Sleep(2000);
        return 0;
    }
}


int update_data(){
    system("cls");
    int flag=0,i,n,t;
    fseek(fp,0,SEEK_SET);//將文件光標回到開頭,防止多次操作導致光標在文件末尾無法讀取到前面的內容
    struct datas data;
    struct datas data2;
    //初始化結構體
    strcpy(data.one,"null");
    strcpy(data.two,"null");
    strcpy(data.three,"null");
    strcpy(data.four,"null");
    strcpy(data2.one,"null");
    strcpy(data2.two,"null");
    strcpy(data2.three,"null");
    strcpy(data2.four,"null");
    char tb_name[10],tb_url[15],haven[16];
    printf("修改數據\n");
    printf("=================\n");
    printf("請輸入要修改數據的表的名字:");
    scanf("%s",tb_name);
    strcpy(tb_url,tb_name);
    strcat(tb_url,".txt\n");
    strcat(tb_name,".txt");
    while(fgets(haven,16,fp)!=NULL){//一行一個信息????????????????????????????????????
        if(!strcmp(haven,tb_url)){//發現匹配表
            if((fp2=fopen(tb_name,"r"))!=NULL){//只讀
                fp3=fopen("__temp.txt","w");//修改專用文件
                printf("請輸入要修改的行號:");
                scanf("%d",&n);
                fscanf(fp2,"%d\n",&t);
                fprintf(fp3,"%d\n",t);
                n++;//防止第二行被改
                for(i=0;i<t;i++){
                    printf("請輸入第%d個字段名:",i+1);
                    switch(i){
                        case 0:scanf("%s",data2.one);break;
                        case 1:scanf("%s",data2.two);break;
                        case 2:scanf("%s",data2.three);break;
                        case 3:scanf("%s",data2.four);break;
                    }
                }
                i=1;//對齊
                while(fscanf(fp2,"%22s%22s%22s%22s\n",data.one,data.two,data.three,data.four)!=EOF){
                    if(i==n){
                        fprintf(fp3,"%22s%22s%22s%22s\n",data2.one,data2.two,data2.three,data2.four);
                    }
                    else{
                        fprintf(fp3,"%22s%22s%22s%22s\n",data.one,data.two,data.three,data.four);
                    }
                    i++;
                }
                fclose(fp2);
                remove(tb_name);//刪除舊文件
                fclose(fp3);//注意順序
                rename("__temp.txt",tb_name);//重命名
                printf("修改數據成功!\n");
                Sleep(1000);//讀取任意鍵,達到暫停的效果
                return 0;//跳出循環
            }
            else{
                system("cls");
                printf("文件出錯\n");
                printf("你有以下兩個選擇\n");
                printf("=================\n");
                printf(" 1.重新修改\n 2.結束脩改表\n 3.退出程序\n");
                printf("=================\n");
                printf("請輸入你的選擇:");
                scanf("%d",&flag);
                if(flag==1){
                    return 1;//再次創建
                }
                if(flag==2){
                    return 0;//跳出循環
                }
                if(flag==3){
                    exit(0);
                }
                else{
                    printf("沒有該選項!\n結束脩改");
                    return 0;
                }
            }
        }
    }
    //匹配成功的都出去了,匹配失敗纔會執行下面的語句
    system("cls");
    printf("庫裏沒有這個表");
    printf("你有以下兩個選擇\n");
    printf("=================\n");
    printf(" 1.修改另一個表的數據\n 2.取消修改表操作\n 3.退出程序\n");
    printf("=================\n");
    printf("請輸入你的選擇:");
    scanf("%d",&flag);
    if(flag==1){
        return 1;//再次創建
    }
    if(flag==2){
        return 0;//跳出循環
    }
    if(flag==3){
        exit(0);
    }
    else{
        printf("沒有該選項!\n結束脩改");
        Sleep(2000);
        return 0;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章