天天看點

作業系統---實驗一、指令解釋程式的編寫實驗

實驗一、指令解釋程式的編寫實驗

一、        實驗目的

(1)掌握指令解釋程式的原理;

(2)*掌握簡單的DOS調用方法;

(3)掌握C語言程式設計初步。

二、        實驗内容和要求

根據教師指定的實驗課題,完成設計、編碼、測試工作。

三、        實驗方法、步驟及結果測試

  1. 1.      源程式名:MiniOS1.0.cpp

可執行程式名:MiniOS1.0..exe

  1. 2.      原理分析及流程圖

存儲結構:結構體數組

原理分析:根據實驗要求,該程式需要顯示一個類似window系統dos視窗的界面,使用者輸入指令後在存儲的指令資訊中尋找是否存在相應的指令,并進行相關的處理或提示相應的資訊。

實驗流程:閱讀實驗要求à規劃程式結構à把程式分為多個部分à完善各個部分à把各個程式段結合起來à調試

程式運作流程:顯示版本資訊à讀取指令資訊的檔案cmd.txt到結構體數組中à等待使用者輸入指令à在結構體數組中尋找是否存在該指令à(存在,則進行相應的處理貨提示該指令的作用/不存在,則提示該指令不存在)à回到等待使用者輸入指令的操作。

  1. 3.      主要程式段及其解釋:

結構體:

struct Ordersave

{

    char order[10];//儲存指令

    char type[3];//指令類型

    char mean[50];//指令作用

};

主函數:

int n;//記錄讀入指令資訊的條

    Ordersave dos[MAX];

    char msg[50];

    //從本地檔案讀取全部指令資訊

    printf("Microsoft Window [版本 6.1.7016]\n版權所有 <c> 2009 Microsoft Corporation。保留所有權利。\n");

    n=readMsg(dos);

    while(1)

    {

           //讀取使用者輸入的指令

           inputMsg(msg);

           //寫日志,記錄輸入的指令和輸入的時間

           writeLog(msg);

           //處理使用者輸入的指令

           dealMsg(dos,msg,n); 

    }

readMsg函數:

功能:從檔案cmd.txt中讀取指令資訊

while(!feof(fp))

           j=0;

           k=0;

           //按行讀取

           fgets(s,800,fp);

           s[strlen(s)]='\0';

           if(s[strlen(s)-1]==10)    //去掉Enter鍵

                  s[strlen(s)-1]='\0';

           if(s[k]!='\0')

           {

                  while(s[k]!='\t')

                  {

                         dos[i].order[j]=s[k];

                         j++;

                         k++;

                  }

                  dos[i].order[j]='\0';

                  k++;

                         if(s[k]=='0')

                                strcpy(dos[i].type,"外");

                         else

                                strcpy(dos[i].type,"内");

                  j=0;

                  while(s[k]!='\0')

                         dos[i].mean[j]=s[k];

                  dos[i].mean[j]='\0';

           }

           i++;

inputMsg函數:

功能:顯示輸入的提示

printf("\nC:\\User\\Administrator>");

    gets(msg);

dealMsg函數:

功能:尋找是否存在指令并進行相應的處理貨提示

if(strcmp(msg,dos[i].order)==0)

                  if(strcmp(msg,"cls")==0)

                         //清屏

                         system("cls");

                  else if(strcmp(msg,"help")==0)

                         //輸出全部指令

                         int j=0;

                         while(j<n)

                         {

                                printf("%s\t%s部指令\t%s\n",dos[j].order,dos[j].type,dos[j].mean);

                                j++;

                         }

                  else if(strcmp(msg,"time")==0)

                         time_t t;//定義一個時間變量

                         struct tm *at;//定義為結構體的資料類型友善閱讀

                         char now[80];//定義一個字元串用來儲存擷取到的日期和時間

                         time(&t);//擷取目前時間(以秒數表示)

                         at=localtime(&t);//擷取目前時間和日期并轉換為本地時間

                         strftime(now,79,"目前時間: %H:%M:%S",at);//根據區域設定格式化本地時間/日期,函數的功能将時間格式化,或者說格式化一個時間字元串

                         puts(now);

                         printf("輸入新時間:");

                         char temp[20];

                         gets(temp);

                  else if(strcmp(msg,"date")==0){

                         char week[]={"日一二三四五六"};

                         char weekNum[2];

                         strftime(weekNum,79,"%w",at);

                         strftime(now,79,"目前日期: %Y/%m/%d ",at);//根據區域設定格式化本地時間/日期,函數的功能将時間格式化,或者說格式化一個時間字元串

                         printf("%s星期%c%c\n",now,week[(weekNum[0]-48)*2],week[(weekNum[0]-48)*2+1]);

                         printf("輸入新日期: <年月日> ");

                  }           

                  //判斷是否選擇退出

                  else if(strcmp(msg,"exit")==0){

                         exit(0);

                  else

                         printf("'%s' ",dos[i].order);

                         printf("%s部指令輸入正确!\n",dos[i].type);

                         printf("該指令的作用是:%s\n",dos[i].mean);

                  canfine = true;

                  break;

writeLog函數:

功能:記錄使用者輸入的指令到log.txt中,沒有該檔案則建立一個再儲存

    if((fp = fopen("log.txt","a"))==NULL)

           fp=fopen("log.txt","w");

    fputs(msg,fp);

    fputs(now,fp);//now為儲存格式化系統時間後的數組

    fclose(fp);

cmd.txt中儲存的資料為:

dir       1     顯示一個目錄中的檔案和子目錄

cd              1     顯示目前目錄的名稱或将其更改

md      1     建立一個目錄

rd        1     删除目錄

cls       1     清除螢幕

date    1     顯示或設定日期

time    1     内部指令顯示或設定系統時間

ren      1     重新命名檔案

copy   1     将至少一個檔案複制到另一個位置

help    0     提供Window指令的幫助資訊

exit     0     退出指令解釋程式

 源代碼位址 https://github.com/helloyoucan/MiniOS

  1. 4.      運作結果及分析

運作結果:

作業系統---實驗一、指令解釋程式的編寫實驗
作業系統---實驗一、指令解釋程式的編寫實驗
作業系統---實驗一、指令解釋程式的編寫實驗
作業系統---實驗一、指令解釋程式的編寫實驗

實驗結果符合預料的結果。

四、        實驗總結

難點1:在讀取指令資訊時,不能正确地讀取并儲存到結構體中。

解決辦法:分行讀取,一行儲存着指令,指令類型及作用,需要分三個不同的位置讀取,用制表符作為讀取位置的區分。

難點2:儲存指令類型的方法是用0和1差別的,但實際要求輸出的是字元串類型。

解決辦法:在讀取時,根據讀取到的0或1,用strcpy的方法儲存“外”或“内”到結構體數組中。

難點3:未曾試過用C語言讀取系統時間并輸出。

解決辦法:翻書尋找和在網絡上尋找,最終在網絡上找到一個大緻符合自身要求的方式,加以修改後為自己所用。

難點:4:使用者輸入date時,需要輸出中文的星期幾,但在讀取時讀取到的隻有英文的星期幾或0到6的數字。

解決辦法:用一個字元串數組儲存日“一二三四五六”,再利用讀取到的0到6之間的數字作為數組下标,但又遇到一個問題,漢字占的位置為2個字元,輸出一個字需要同時輸出儲存着兩個半個漢字的字元才能輸出一個漢字,是以用讀取到的數字乘2和讀取到的數字乘2加一作為數組下标,同時輸出兩個字元,即輸出“日一二三四五六”中的一個漢字。

心得體會:在看到實驗要求時,根本不知道如何才能做出如實驗結果截圖顯示的程式,在開始實驗時,我并不是一味一行一行寫代碼,而是先建構好程式的結構,寫好程式大緻需要哪些功能,再把每一個功能分為一個函數,然後再完善每一個函數。在寫每一個程式時,首先需要的不是馬上寫出代碼,而是先把程式的結構功能細緻厘清,分開為很多的一小部分,再一部分一部分地寫好,再結合為一個整體。