<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      實現對C語言類學生管理系統文件存儲的兩種方法

      學習javascript的時候曾經想做一個留言板的應用,但是卻由于不知道如何存儲失敗了,由于做這個留言板的思路類似于C語言的學生管理系統,故此這次經歷讓我重新審視自己去學懂C語言的文件操作。
      

      我重新用C語言寫了一個留言板系統,當時學習C的時候被學生管理的課設折騰的死去活來,但后來才知道,其實不管是飛機訂票還是留言還是學生管理,這類課程設計本質上都要求你用語言去實現一個CRUD完備的應用系統,設計這種系統實際上是一種基本功,而這種系統如果再加上網絡通信以及存儲(文件或者數據庫),就可以稱為真正的軟件。

      廢話不多說,代碼結構如下:

      main.c

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <ctype.h>
      
      #include "function.h"
      #include "LinkList.h"
      
      int main()
      {
          LNode L;
          InitList(&L);
          loadFromFile(&L);
          while (1)
          {
              switch (menu())
              {
              case 1:
                  add(&L);    //1.添加評論功能
                  break;
      
              case 2:
                  view(&L);   //2.瀏覽所有評論
                  break;
      
              case 3:
                  del(&L);    //3.刪除評論
                  break;
      
              case 4:
                  modify(&L); //4.修改評論
                  break;
      
              case 5:
                  exit(0);
      
              default:
                  fflush(stdin);
                  printf("請勿暴力測試!\n");
                  break;
              }
          }
      }
      

      function.h 負責應用的功能實現,要用到鏈表

      #ifndef FUNCTION_H_
      #define FUNCTION_H_
      
      #include"LinkList.h"
      
      int menu(); //榮單,每次功能使用結束后翻會調用訊視頻 圖片
      void loadFromFile(LNode *L); //從文件加載數據
      void saveToFile(LNode *L);   //保存數據到文件中
      void s_gets(char *srcText);  //處理輸入的字符串
      void printOne(LNode *p) ;//用于單條評論的打印
      void add(LNode *L);      //添加評論功能
      void view(LNode *L);     //瀏覽所有評論
      void del(LNode *L) ;     //刪除評論
      void modify(LNode *L);   //修改評論
      #endif
      

      LinkList.h 鏈表的設計

      #ifndef LINKLIST_H_
      #define LINKLIST_H_
      
      #define MAX_SIZE 100
      struct comment //學生的數據,目前只有評論,可再擴展出學號,用戶名,日期等信息
      {
          char text[MAX_SIZE];
      };
      typedef struct LNode //學生的數據用鏈表存儲
      {
          struct comment comment;
          int id; //節點序號
          struct LNode *prev;
          struct LNode *next;
      } LNode;
      LNode *head;
      LNode *tail;
      
      void InitList(LNode *L);                //初始化鏈表
      LNode *InsList_FromTail(LNode *L);      //尾插法添加鏈表
      LNode *InsList_FromHead(LNode *L);      //頭插法添加鏈表
      int ListLength(LNode head);             //測量表長度
      void DelList(int index, LNode *L);      //按序號刪除鏈表
      
      #endif
      

      C語言對文件通信提供了四種函數:fprintf, fscanf, fread,fwrite。

      方法一:fprintf和fscanf

      起初的思路是使用fprintf和fscanf,每次添加評論時用一個整形變量datalen統計數據長度并將數據寫入文件,最后將datalen寫入另一個文件中存儲起來;

      而讀取文件時,按照datalen的大小重新構造鏈表,并將文件的相關數據重新填入鏈表。

      但這樣有很多不便性,對于存儲了評論的文件, 要十分關注文件指針在文件中的位置,換行符等特殊字符對文件讀取的影響(\n在文件中被fp視為2個字符),在用鏈表存取的成員值只有一兩個時還好,要是評論還有用戶名,發言時間,地點等更多的屬性時,不僅每次都要修改代碼,由于數據是以文本顯示,屆時用文件指針讀入數據,乃至穩定顯示數據將是一個復雜的挑戰,

      但我還是動手實踐了一下,借此經歷我復習了這兩個函數的用法以及文件指針如何操作:

      (此外還把《C Primer Plus》中統計行數,詞數的程序重新實踐了一遍)

      偽代碼表示為:

      loadFromFile函數:

      打開數據文件data.txt和記錄數據長度的文件len.txt

      如果打不開,程序返回錯誤,反之程序繼續執行

      從len.txt獲取文件長度datalen

      for(i->datalen),

      每次用頭插法構建一個新節點表,就從data.txt獲取一個節點的評論數據

      將數據導入到新建的節點中

      導入完畢,關閉文件

      saveFromFile 函數:

      檢查是否能打開數據文件data.txt

      向里面覆寫鏈表中的所有數據,同時記錄數據長度

      覆寫完畢后關閉文件,數據保存到磁盤文件內

      void loadFromFile(LNode *L) //從文件加載數據
      {
        LNode *p;
      
        FILE *fp,*num;
      
        int i, datalen;
      
        char line[MAX_SIZE];
      
      
        if ((fp = fopen(filePath, "r")) == NULL)
      
        {
      
      ?    fprintf(stdout, "Can't Open data file,Read failed\n");
      
      ?    exit(EXIT_FAILURE);
      
        }
      
        else if ((num = fopen(lenPath, "r")) == NULL)
      
        {
      
      ?    fprintf(stdout, "Can't Open data file,Read failed\n");
      
      ?    exit(EXIT_FAILURE);
      
        }
      
        else
      
        {
      
           fprintf(stdout, "數據文件讀取成功!\n");
      
        }
      
      
      
        fscanf(num, "%d", &datalen);		//從文件開頭獲取數據長度
      
        printf("當前評論數: %d條\n", datalen);
      
      
        for (i = 0; i < datalen; i++) //根據數據長度重建鏈表并賦值
      
        {
      
      ?    p = InsList_FromTail(L); //id,前后指針是鏈表的固有屬性,但comment不是,所以需要賦值
      
      ?    
      
      ?    fgets(line,MAX_SIZE,fp); 
      
      ?    strcpy(p->comment.text, line);
      
        }
      
      
        fclose(num);
      
        fclose(fp);
      
      }
      
      
      
      void saveToFile(LNode *L)   //保存數據到文件中
      {
          FILE *fp = NULL,*num = NULL;
          LNode *p;
          int datalen = 0; //統計數據量
          if ((fp = fopen(filePath, "w+")) == NULL)
          {
              fprintf(stdout, "Can't Open data file,Read failed\n");
              exit(EXIT_FAILURE);
          }
          else if ((num = fopen(lenPath, "w+")) == NULL)
          {
              fprintf(stdout, "Can't Open data file,Read failed\n");
              exit(EXIT_FAILURE);
          }
      
          for (p = L->next; p != NULL; p = p->next)
          {
              fprintf(fp, "%s", p->comment.text); //將每個節點的所有數據依次寫入文件
              datalen++;
          }
        
          fprintf(num, "%d", datalen);  //用另一個文件標記數據的長度
      
          fclose(num);
          fclose(fp);
      }
      
      方法二 :fread和fwrite

      基本步驟和思路一類似,只不過操作對象從文本變為了二進制數據,得以直接規定用每個節點大小的數據塊去寫入文件以及賦值給結構體comment,而且由于可用feof判斷臨界條件,故也不需要用datalen判斷數據量了,且comment的結構體成員變動時也不需改代碼,整體上方便了許多;

      代碼如下:

      void loadFromFile(LNode *L) //從文件加載數據
      {
          LNode *p, *newNode;
          FILE *fp;
          int order = 1;
          char line[MAX_SIZE];
      
          p = L;
          if ((fp = fopen(filePath, "rb")) == NULL)
          {
              fprintf(stdout, "Can't Open data file,Read failed\n");
              exit(EXIT_FAILURE);
          }
          else
          {
              fprintf(stdout, "數據文件讀取成功!\n");
          }
      
          while (1)
          {
              newNode = (LNode *)malloc(sizeof(LNode));
              fread(&newNode->comment, sizeof(comment), 1, fp);
              if (feof(fp))
                  break;
              p->next = newNode;
              newNode->prev = p;
              newNode->id = order++;
              newNode->next = NULL;
              p = newNode;
          }
      
          fclose(fp);
      }
      
      void saveToFile(LNode *L) //保存數據到文件中
      {
          FILE *fp;
          LNode *p;
      
          if ((fp = fopen(filePath, "w+b")) == NULL)
          {
              fprintf(stdout, "Can't Open data file,Read failed\n");
              exit(EXIT_FAILURE);
          }
          else
          {
              fprintf(stdout, "數據文件讀取成功!\n");
          }
      
          if (L->next != NULL)
          {
              for (p = L->next; p != NULL; p = p->next)
              {
                  fwrite(&p->comment, sizeof(comment), 1, fp); //依次把各結點數據"倒入"文件
              }
          }
          else //如果鏈表都被刪光了
          {
              fclose(fp);
              return 0;
          }
      
          fclose(fp);
      }
      

      到此講述了文件存儲的兩個方法,其實都算是同一種思路,就是如果鏈表中內容出現了變動,就打開文件將變動的鏈表內容覆寫進去;

      而加載文件時,根據鏈表的長度(或者文件是否eof)來判斷為存儲數據新建多少個鏈表節點。

      但是這種存儲方式還是有一些不足,不如說是C文件存儲本身的設計缺陷,

      如果要添加新的內容其實不需要覆寫文件,直接將文件指針fseek到最后把新增的內容寫入就行,

      但如果要指定刪除某一節點的內容的話,要么將修改后的內容覆寫到文件,要么就將要刪除內容前后的部分分別寫到兩個額外文件中重拼起來,然后將原文件刪掉,將重拼的文件命名為原文件名,

      但是兩種方法都必須破壞原文件(一個內容上,一個直接刪除)。

      1612080240275

      我設想直接把文件的指定內容刪除就行,被刪除內容后端的內容會自動上升與前端的內容結合,上面操作全都只在數據文件中執行,不需要額外的文件,但似乎沒有如此的方法。

      IMG_20210131_161335

      如果這不是一個1kb文件,而是幾十GB乃至更大的大小,執行上述操作(覆寫,復制)所浪費的程序性能可想而知,興許隨著的之后的學習我會為此采用數據庫來改進存儲。

      我的留言板系統源碼已發到gitee上,歡迎大家學習:

      https://gitee.com/tracker647/my-crudpractice

      posted @ 2021-01-31 17:18  另一種開始  閱讀(505)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲无线一二三四区手机| 久久这里只有精品首页| 锡林浩特市| 国产一区二区不卡91| 珲春市| 亚洲另类欧美在线电影| 丰满爆乳一区二区三区| 老司机午夜免费精品视频| 奇米影视7777久久精品| 草裙社区精品视频播放| 久久精品久久电影免费理论片| 伊伊人成亚洲综合人网香| 性视频一区| 日韩精品在线观看一二区| 国产曰批视频免费观看完| 丁香婷婷激情综合俺也去| 蜜臀91精品高清国产福利| 91中文字幕在线一区| 平原县| 人与禽交av在线播放| 欧美 喷水 xxxx| 女人张开腿让男人桶爽| 清纯唯美人妻少妇第一页| 中文字幕在线观看一区二区| 亚洲av成人午夜福利| 亚洲中文字幕五月五月婷| 惠东县| 无码日韩av一区二区三区| 国产成人高清精品免费软件| 在线观看AV永久免费| 国产精品无码一区二区牛牛| 国产色a在线观看| 思思热在线视频精品| 国产94在线 | 亚洲| 九九热精品在线免费视频| 日韩精品亚洲专在线电影| 另类 亚洲 图片 激情 欧美| 中文字幕国产精品第一页| 欧美成人午夜精品免费福利| 国产成人精品亚洲精品密奴| 亚洲色大成网站WWW久久|