1.本章學習總結
1.1 學習內容總結
1.結構體如何定義、成員如何賦值
1.結構體的定義
- 一般形式:
struct 結構名{
類型名 結構名成員1;
類型名 結構名成員2'
···
類型名 結構名成員n;
};
- 結構的定義以分號結束,因為C語言中把結構定義看做一條語句
- 關鍵字struct和結構名必須聯合使用,因為它們合起來表示一個數據類型名。
- 結構的嵌套定義:
/*設置結構體保存學生的學號,姓名,通行地址,以及計算機,英語,數學和平均成績,其中通行地址包括,居住的城市,街道,門牌號,郵編*/
struct address {
char city[10];
char street[20];
int code;
int zip;
};
struct nest_student{
int num;
char name[10];
struct address addr;
int computer,english,math;
double auerage;
};
注意:在注意嵌套的結構類型時,必須先定義成員的結構類型,在定義主結構類型。
- 運用typedef語句
- typedef用於給基本數據類型和導出數據類型定義一個新的名字。一般形式為
typedef 老的變量類型 新的變量類型
,這樣做的好處是后面定義結構體變量時不需要寫關鍵詞strcut,使用起來比較方便。
- typedef用於給基本數據類型和導出數據類型定義一個新的名字。一般形式為
2.結構體成員的賦值
- 在c語言中,使用結構成員操作符"."來引用結構成員,格式為
結構變量名.結構成員名
。
/*對學生的信息進行賦值*/
struct student{
int num;
char name[10];
int computer,english,math;
double average;
};
struct student s1,s2;
/*分別對s1的每個結構體成員賦值;*/
scanf("%d %s %d %d %d",&s1.num,s1.name,&s1.computer,&s1.english,&s1.math);
s1.average=(s1.computer+s1.math+s1.english)/3.0;
/*將s1中各個結構體成員的值賦給s2*/
s2.num=s1.num;
strcpy(s2.name,s1.name); //這里注意,對字符串的賦值,不可以直接寫“s2.name=s1.name”,這樣的寫法是錯誤的,要用庫函數strcpy()!
s2.math=s1.math;
s2.computer=s1.computer;
s2.english=s1.english;
s2.average=s1.average;
/*對於將兩個相同類型的結構變量,把一個結構變量賦給另外一個結構變量,可以直接整體賦值,這樣和分別對結構體成員的賦值的操作等效*/
s2=s1;
運行結果:
- 定義結構指針變量,使用指向運算符->訪問指針指向的結構成員,以此來給每個結構成員賦值;
struct student *p;
/*使結構指針變量p指向s1,從鍵盤上讀取數據賦給p指向的s1*/
p=&s1;
scanf("%d %s %d %d %d",&p->num,p->name,&p->computer,&p->english,&p->math);
p->average=(p->computer+p->english+p->math)/3.0;
/*使結構指針變量p指向s2,再把s1中各個結構體成員的值賦給s2*/
p=&s2;
p->num=s1.num;
strcpy(p->name,s1.name);
p->math=s1.math;
p->computer=s1.computer;
p->english=s1.english;
p->average=s1.average;
運行結果:
2.結構體數組排序做法
1.選擇排序
/*從大到小排序*/
struct student students[n];
struct student temp;
for i=0 to n-1//外循環
for j=0 to n//內循環
if(students[j]>student[i])//如果后面的數據比前面大,交換數據;
temp=students[i];
student[i]=student[j];
student[j]=temp;
end if
end for
end for
運行結果:
2.冒泡排序法
struct student students[n];
struct student temp;
for i=1 to n
for j=0 to n-i
if(students[j+1]>student[j])
temp=students[j];
student[j]=student[j+1];
student[j+1]=temp;
end if
end for
end for
運行結果:
3.結構體指針
1.概念
- 就是指向結構類型變量的指針。
- 一般形式
struct 結構名 * 指針變量名
2.用結構指針訪問結構成員
struct student *p;
p=&s1;
-
用*p訪問結構成員:
-
用指向運算符->訪問指針指向的結構成員:
3.結構指針作為函數參數
將學生的信息按平均分排名
雖然結構變量也可以做為函數參數,但是當結構成員數據很多時,在參數傳遞時過程就需要消耗很多空間,而使用結構指針作為函數參數只要傳遞一個地址值,可以提高傳參效率。
4.共用體、枚舉類型做法
1.共用體
- 一般聲明形式:
union 聯合名
{
成員聲明
成員聲明
···
}變量列表
- 聯合中的所有成員共享同一塊內存,內存長度為最長成員的長度。因為在后續的程序設計中,代碼量越來越多,內存是非常寶貴的。
2.枚舉
- 一般聲明形式:
enum 枚舉名 {枚舉值1,枚舉值2,···}變量列表;
- 每個枚舉值應該是一個合法的標識符,或者是一個標識符后面跟上一個等號,再加上一個常量表達式。
- 編譯程序將從0開始逐個給枚舉值賦值,如果某個枚舉值標識符后面跟有等號和常量表達式,那么編譯程序就將該常量表達式的值作為該枚舉值的值,該枚舉值后面的枚舉值從這個枚舉值開始逐個加1,重新編號。
5.文件和緩沖系統
- 1.文本文件和二進制文件
- 數據文件可分為文本文件和二進制文件。
- 文本文件是以字符ASCII碼值進行存儲與編碼的文件,文件內容就是字符,可通過“記事本”等編輯工具來對文件內容進行查看,修改等。
- 二進制文件就是存儲二進制數據的文件,它包含的是計算機才能識別的機器代碼,如果用編輯器工具打開,就會看到一堆亂碼,因為無法用編譯器工具打開,所以二進制文件比文本文件更安全。
- 2.緩沖文件系統
- 程序與文件的數據交換葯通過內存緩沖區來進行,根據這種文件緩沖的特性,把文件系統分為緩沖文件系統與非緩沖文件系統。
- 對緩沖文件系統,在進行文件操作時,系統自動為每一個文件分配一塊文件內存緩沖區(內存單元),C程序對文件的所有操作就通過對文件緩沖區的操作來完成。緩沖區文件系統的大小是由具體的C語言版本決定。
- 對非緩沖文件系統,文件緩沖區不是由系統自動分配的,而需要程序員在程序中用c語言實現分配。
6.文件結構與文件類型指針
- 1.文件結構
- FILE是一個結構類型,用typedef語句來進行命名的,typedef語句在頭文件stdio.h中定義,因此使用文件的程序都要
#include <stdio.h>
- FILE是一個結構類型,用typedef語句來進行命名的,typedef語句在頭文件stdio.h中定義,因此使用文件的程序都要
- 2.文件類型指針
- 一般形式:
FILE * fp
- FILE是文件類型定義符,fp是文件類型的指針變量。
- 這里的文件指針fp做自增的話,比如++fp,表示的是fp指向下一個FILE結構(如果存在),而不是指向文件中的下一個數據
- 一般形式:
7.打開文件和關閉文件
1.打開文件
- 一般調用形式為
fopen("文件名","文件打開方式");
,這里的文件名要指出對哪個具體文件進行操作,一般要指定文件的路徑,如果不寫出路徑在,則默認與應用程序的當前路徑相同。文件路徑若包含絕對完整路徑,則定位於目錄用的斜桿“\”需要用“\”,因為''在c語言中表示轉義符,"\"表示實際的""。 - fopen函數有返回值。如果執行成功,函數將返回包含文件緩沖區等信息的FILE結構地址,賦給文件指針fp,否則返回一個NULL(空值)的FILE指針。
- 在調用fopen函數時最好做一個判斷,以確保文件正常打開后再進行讀寫。
if ((fp=fopen("abc.txt","r"))==NULL)
{
printf("File open error!");
exit(0);//exit(0)是系統標准函數,作用是關閉所有打開的文件,並終止程序的執行。
}
- 文件打開方式:
- 文本文件(ASCII)
打開方式 | 含義 |
---|---|
"r" | 打開文本文件進行只讀,該文件必須存在 |
"w" | 建立新文本文件進行只寫 |
"a" | 打開文本文件進行追加,如果該文件不存在就新建一個文件 |
"r+" | 打開文件進行讀/寫,對文件進行寫時會把文件中的內容覆蓋,該文件必須存在。 |
"w+" | 建立新文件進行讀/寫,如果該文件存在就會把原來的文件刪除,再建一個新的文件 |
"a+" | 打開文本文件進行讀/寫/追加,如果該文件不存在,就新建一個文件 |
- 二進制文件打開的操作和文本文件一樣,只不過打開方式多了一個字符“b”。
2.關閉文件
- 一般形式:
fclose(文件指針);
- 若該數為0表示正常關閉文件,否則表示無法正常關閉文件,所以關閉文件也應該使用條件判斷:
if(fclose(fp))
{
printf("Can not close the file!\n");
exit(0);
}
8.文件讀寫,文件中數據如何讀進結構體數組
- C語言標庫stdio.h中提供了一系列文件的讀寫操作函數:
函數 | 調用格式 | 功能 |
---|---|---|
fgetc() | fgetc(FILE*fp) | 從fp指向的文件中得到一個字符 |
fputc() | fputc(char ch ,FILE*fp) | 把字符ch輸入到fp指向的文件中去,成功的話返回ch,失敗則返回EOF(在頭文件stdio.h中有說明其值為-1) |
fgets() | fgets(charp,n,FILEfp) | 從fp指向的文件中獲取n-1個字符賦給指針p所指向的字符串,昂函數讀取的字符達到指定的個數,或者接收到換行符,或接收到文件結束標志EOF時,在讀取的字符后面自動添加一個'\0'字符,如果讀取成功則返回字符串,否則返回空指針,此時字符串的內容不確定 |
fputs() | fputs(charp,FILEfp) | 把p指向的字符串輸到fp指向的文件中去 |
fscanf() | fscanf(文件指針,格式字符串,輸入表) | 從文件中按照給定的控制格式讀取數據 |
fprintf() | fprintf(文件指針,格式字符串,輸出表) | 從文件中按照給定的控制格式讀取數據保存到變量 |
fread() | fread(buffer,size,count,fp) | 從二進制文件中連續讀入count個數據塊(size個字節)到buffer所指向的變量中 |
fwrite() | fwrite(buffer,size,count,fp) | 向二進制文件中連續輸出入count次buffer所指向的變量中數據塊(size個字節) |
- 調用函數feof()可以檢測文件指針fp所指文件的位置是否到了文件末尾。該函數在打開文件是文件指針是指向文件首部的,每次調用一個讀取文件中的數據的讀取函數成功后,文件指針fp會自動向后移動到還未被讀取的數據去,如果文件指針指向文件末尾時,則會返回一個無效的字符EOF,因為EOF不是常規的ASCII碼,而是一個值為-1的常量,這樣可以區分於文件中的字符內容。
9.其他相關函數
和文件有關的其他函數 | 調用格式 | 功能 |
---|---|---|
rewind() | rewind(FILE*fp) | 使文件指針fp指向文件的首地址 |
fseek() | fseek(FILE*fp,long offset,from) | offset表示從當前位置開始向前或者向后偏移的長度,from表示從哪個位置開始計算偏移量,from可取三個值“SEEK_SET,SEEK_CUR,SEEK_END”,分別表示文件首部,當前位置和文件尾部,實際表示的值為0,1,2. |
ftell() | ftell(FILE*fp) | 獲取當前位置距文件開頭的位移量(字節數),成功則返回位移量,失敗時返回-1L |
clearer() | clearer(FILE*fp) | 用來清除出錯標志和文件結束標志,使它們為0值 |
1.2本章學習總結
-
學習體會:c語言學到最后,學習的東西越來越多,雖然這學期我們就要結束c語言的課程,可一寫題目才發現自己還有許多東西都還沒有學習,很多東西也還一知半解,到了后面綜合性越來越強,如果前面有落下的知識應該要及時去補上,否則這部分的內容理解起來就會有些困難。(沒錯就是我555)
-
代碼量:1890
2.綜合作業--“我愛成語”
2.1.文件介紹
頭文件介紹
頭文件1.idiom.h
- 結構體及功能
結構體 | 功能 |
---|---|
IDIOM | 從idiom.h文件中讀取成語及其意思 |
RANK | 從ranking.h文件中讀取排名成績和時間 |
- 函數聲明
函數 | 功能 |
---|---|
void Theme() | 主題 |
void Login(char*user) | 登入界面 |
int IsUser(char* name_str, char* password_str) | 判斷是否為用戶 |
void GetChoice(FILE* fp1, FILE* fp2, char* user) | 得到用戶的選擇並進入該功能 |
int Game(FILE* fp1, FILE fp2 ,char user) | 成語游戲 |
int GetIdiom(FILE* fp, IDIOM* idioms) | 獲得文件idiom.txt中的所有成語 |
void RightSentence() | 誇獎的句子 |
void WorrySentence() | 提示回答錯誤的句子 |
int Problems(int num,IDIOM *idioms) | 隨機得到一個成語,並判斷是否正確 |
void PrintProblem(char* idiom) | 隨機挖空,輸出題目 |
void ArrageRank(FILE* fp, char* user, int right) | 在文件ranking.txt中更新排名 |
void GetTime(RANK*rank_ptr) | 獲取當前時間和日期的函數 |
void GetScore(int right, int count) | 計算正確率並告知答題結束 |
int NowTime() | 記錄當前時間 |
void GetRank(FILE*fp) | 獲取排名 |
int FindIdiom(FILE*fp) | 查找成語 |
int WriteNewIdiom(FILE*fp) | 添加新成語 |
int CheckIdiom(FILE* fp, char* idiom) | 查看文件中是否有相同的成語 |
int IsAgain() | 判斷是否要繼續的函數 |
- 代碼截圖
2.函數實現文件介紹。
1.idiomMain.cpp
- 功能:只放一個主函數main,在主函數中打開文件,得到用戶名字,這三個變量的使用率比較高,放入主函數中,比較容易傳參。
- 代碼截圖:
2.List.cpp
-
void Theme()
- 功能:放在開頭的一個小界面,保存有清屏和再輸出小界面的功能。
- 代碼截圖:
-
void PrintLine()
- 功能:輸入分割線,用於分割題目。
- 代碼截圖:
-
void Login(char user)*
- 功能:登入界面,讀取用戶輸入的用戶名和密碼,並將登陸成功的用戶名傳回主函數,這樣便於主函數傳給下一個函數。
while(1)
輸入用戶的名字和密碼,分別賦給name,password;
if(IsUser(name,password)==0)
說明輸入的名字和密碼錯誤,不跳出循環;
else
說明輸入的名字和密碼正確,break跳出循環;
end if
end while
把用戶的名字name保存到變量user,傳給其他函數使用;
-
代碼截圖:
-
int IsUser(char name, char password)**
- 功能:判斷是否為用戶,如果輸入不正確將一直無法繼續下一個步驟,直到輸入正確的用戶名和密碼。這里打開文件user.txt,將從Login函數中得到的用戶名和密碼與文件中的用戶和賬號作比較,因為沒有其他功能會用到這個文件,所以用完文件后就可以直接關閉文件,及時釋放不用的文件緩沖區單元。
定義字符數組name_str[M],password_str[M]分別保存從文件中讀到的用戶名字和密碼;
打開文件user.txt;
while(!feof(fp))//遍歷文件;
if(strcmp(name,name_str)==0&&strcmp(password,password_str)==0)//說明用戶名和密碼都匹配;
return 1;
end if
end while
關閉文件;
return 0;//說明不匹配,用戶輸入的名字和密碼不匹配;
-
代碼截圖:
-
void ChoiceMenu()
- 功能:選擇菜單,給用戶提示,供用戶選擇。
- 代碼截圖:
-
void GetChoice(FILE * fp1,FILE * fp2,char * user)
- 功能:獲取用戶的選擇,並進入相應的分支,對輸入錯誤的選項將會使用戶重復輸入。這里在選擇進入哪個分支的部分加入了循環結構,並把執行每個功能的函數類型都設置為int型,可返回一個數值,這樣可以供用戶選擇是否要繼續執行該選擇。
while(1)
while(1)
輸入選項賦給choice;
if(choice<1||choice>5)//用戶輸入了一個錯誤的選項;
繼續讓用戶輸入;
else //用戶輸入了正確的選項;
退出該循環;
end if
end while
switch(choice)
{
case 1:while(flag = Game(fp1,fp2,user)); break;//游戲;
case 2:while(flag = FindIdiom(fp1)); break;//查找成語;
case 3:while(flag = WriteNewIdiom(fp1)); break;//添加新成語;
case 4:GetRank(fp2); break;//得到排名;
case 5:return;//退出該循環直接回到主函數;
}
end while
- 代碼截圖:
3.idiom.cpp
-
int IsAgain()
- 功能:判斷用戶是否要繼續執行該選擇,如果得到0的話就退回到函數GetChoice()函數中去;
- 代碼截圖:
-
int Game(FILE * fp1,FILE * fp2, char user)*
- 功能:用戶進入該功能進行猜成語游戲,包含提示游戲開始,記錄正確率,答題時間,可中途退出的功能。
定義結構數組IDIOM idioms[300];//保存從文件idioms.txt中讀取的所有成語及成語的意思;
定義變量right保存用戶做對的題目數量,並初始化為0;
定義變量problem保存用戶想要做的題目數量,並初始化為0;
定義變量worry保存用戶做錯的題目數量;
定義變量num保存從文件中得到的成語總個數;
定義begin保存用戶開始做題的時間;
定義end保存用戶做完題的時間;
scanf("%d",&problem);//讀取用戶想要做的題目數量;
for i=1 to problems
if(Problems(num,idioms))//進入出題函數Problems中進行出題,如果答對會返回非0的值;
right++;
end if
if(IsAgain())//說明用戶輸入0退出該游戲;
進入函數GetScore(right,i)計算當前成績;
進入函數ArrageRank(fp2,user,right)進行排名重新排序;
end if
end for
/*說明用戶做完了題目*/
進入函數GetScore(right,i)計算當前成績;
進入函數ArrageRank(fp2,user,right)進行排名重新排序;
if(IsAgain())//判斷是否要重開一盤游戲,然后把值返回到GetChoice函數中,可以實現是否要繼續重開一盤游戲的功能;
使所有文件指針重新指向文件開頭,以便其他函數使用;
return 1;
else
return 0;
-
代碼截圖:
-
int FindIdiom(FILE * fp)
- 功能:查找成語功能。
定義字符數組idiom[M]保存用戶輸入的成語;
scanf("%s",idiom);//保存用戶輸入的成語;
if(!CheckIdiom(fp,idiom))//進入函數CheckIdiom判斷是否找到該成語;
說明沒有找到該成語;
判斷是否要繼續查找成語(IsAgain())
-
代碼截圖:
-
int CheckIdiom(FILE * fp,char idiom)*
- 功能:檢查是否有相同的成語,這個是查找成語功能的一部分,我把它封裝出來,這樣可以供下面的添加函數功能使用。
定義字符數組idiomStr[N]保存從文件中讀到成語及其意思;
定義變量len保存成語長度;
定義字符指針loc定位冒號的位置;
使文件指針指向文件開頭,使得文件指針可以從文件頭開始遍歷;
while(!feof(fp))
fgets(idiomStr,N,fp);
loc=strchr(idiomStr,':');//定位出冒號的位置;
len=loc-idiomStr;//得到成語的長度;
idiomStr[len]='\0';//將冒號替換成'\0',因為函數strcmp在進行字符串比較時,讀到'\0'就停止比較;
if(strcmp(idiom,idiomStr)==0)//說明找到用戶想要的成語;
idiomStr[len]=':';//重新把冒號黏貼回去;
輸出該成語及其意思;
return 1;
end if
end while
return 0;//說明沒有找到成語;
-
代碼截圖:
-
void GetRank(FILE * fp)
- 功能:得到排名,並輸出排名。
- 代碼截圖:
-
int WriteNewIdiom(FILE fp)*
- 功能:添加新的成語
定義字符數組newIdiom[M]保存用戶輸入的成語;
定義字符數組newMean[N]保存用戶輸入的成語意思;
gets_s(newIdiom);//輸入成語;
/*進入函數CheckIdiom中判斷文件中是否已經存在該成語*/
if(CheckIdiom(fp,newIdiom)
已經存在該成語;
else
gets_s(newMean);//輸入該成語的意思;
fseek(fp,0,2);//定位到文件結尾去補充;
fprintf(fp,"%s:%s",newIdiom,newMean);//寫入文件;
end if
判斷是否要繼續寫入新成語(IsAgain());
- 代碼截圖:
3.Game.cpp
- int GetIdiom(FILE fp, IDIOM idioms)**
- 功能:獲取文件idiom.txt的所有成語,保存到結構體數組IDIOM idioms[]中,並返回成語的總數量;
定義字符數組idiomStr[N]保存從文件中讀取的成語和成語意思;
定義結構體指針IDIOM*ptr來指向結構體數組IDIOM *idioms;
定義變量num來記錄成語的個數,並初始化為0;
定義變量len來保存成語的長度;
fseek(fp,0,0);//使文件指針指向文件開頭,使得文件指針從文件頭開始遍歷;
while(!feof(fp)
fgets(idiomStr,N,fp);
loc=strchr(idiomStr,':');//找到冒號位置;
len=loc-idiomStr;//保存成語的長度;
idiomStr[len]='\0';//把冒號換成'\0',因為strcpy函數只復制'\0'前的字符;
strcpy(ptr->idiom,idiomStr);//把成語保存到結構體數組中的idiom中;
strcpy(ptr->mean,idiomStr+len+1);//把成語意思保存到結構體數組中的mean中;
ptr++;
num++;
end while
return num;//返回成語的個數;
-
代碼截圖:
-
void RightSentence()
- 功能:輸出誇獎的語句。
-代碼截圖:
- 功能:輸出誇獎的語句。
-
void WorrySentence()
- 功能:輸出提示錯誤的語句。
- 代碼截圖:
-
int Problems(int num,IDIOM * idioms)
- 功能:隨機得到一個成語並輸出題目,得到用戶答案判斷是否正確。
定義字符數組problem[M];//保存隨機得到的成語;
定義answer[M];//保存用戶輸入的答案;
定義變量flag用來判斷用戶是否需要提示;
定義變量count來保存用戶回答的次數;
定義變量n來保存隨機數;
定義變量begin來保存用戶開始答題的時間;
定義變量end來保存用結束答題的時間;
srand(time(0)); n=rand()%num;//得到隨機數n;
strcpy(problem,idioms[n].idiom);//將隨機得到的成語賦給problem;
進入函數PrintProblem隨機空兩個字,並輸出題目;
while(count<=3)//設置一道題目只能回答3次;
scanf("%s",answer);//用戶輸入答案;
if(strcmp(answer,problem)==0)//說明答案正確;
end=NowTime();
return 1;
else//說明回答錯誤;
if(flag!=1)//說明還沒使用提示;
scanf("%d",&flag);
if(flag==1)
輸出提示;
end if
end if
end if
count++;
end while
-
代碼截圖:
-
void PrintProblem(char problem)*
- 功能:隨機去掉兩個字,輸出題目;
- 代碼截圖:
-
int NowTime()
- 功能:保存當前時間。
- 代碼截圖:
-
void ArrageRank(FILE fp, char user, int right)**
- 功能:將文件ranking.txt文件中的數據重新排序,更新排名。
定義結構體數組ranks[U];//保存文件中的排名;
定義結構體指針temp;
定義變量userRank保存當前用戶的上次排名;
while(!feof(fp))
for i=0 to U
fscanf(fp, "%s%d%d/%d/%d%d:%d", ranks[i].name, &ranks[i].score, &ranks[i].year, &ranks[i].month, &ranks[i].day, &ranks[i].hour, &ranks[i].minute);//從文件中讀取排名;
if(strcmp(user,ranks[i].name)==0)//找到當前用戶的排名;
userRank=i;
rank[i].score+=right*5;//計算成績;
GetTime(ranks+i);//得到當前的日期和時間;
end if
end for
break;
end while
for i=userRank-1 to 0//從用戶當前的排名開始遍歷,往上比較;
if(rank[i].score<ranks[userRank].score)//說明成績可以超過上面那名選手;
temp=ranks[i];
rank[i]=ranks[userRank];
userRank--;//當前用戶的排名上升了一名;
else
break;//直接退出;
end if
end for
使文件指針指向文件開頭,開始向文件重新輸入排序后的排名;
-
代碼截圖:
-
*void GetTime(RANK rank_ptr) **
- 功能:得到答題結束的時間,運用了函數localtime()可以得到當前的本地時間,但是有個小問題,得到的月份比實際要小1,時間也需要加上1900。
- 代碼截圖:
-
void GetScore(int right, int count)
- 功能:得到正確率並輸出。
- 代碼截圖:
2.2.運行結果
2.3大作業總結
Q1:首先是多個函數都使用了文件指針,如果某個函數的文件指針已經指到文件尾部了,下一個函數調用的時候就會出問題,
A1:所以在所有調用文件指針時,都使用fseek(fp,0,0)使得指針指向文件頭/尾。
Q2:剛開始對題目的輸出處理,總是無法輸出正常的漢字。
A2:單個漢字占兩個字節,如果想要輸出一個漢字只使用一個%c或者兩個%c是不可以實現的,應該要把單個漢字作為字符串處理,於是我利用了printf("%.*s",problem+2);來控制輸出的漢字個數;
Q3:對文件中排名的處理,不知道如何獲取當前的日期和時間,本以為c語言的內容已經學習了很多了,沒想到除了上課學習的還有許多需要我們去拓展的。~~革命還尚未成功啊啊~~
A3:我上網去查找了,知道了函數localtime()將從time()函數中獲得的從1970年1月1日到現在返回的秒數轉換為當前的年,月,份,時,分,秒形式;但是實際年份還要加上1900,月份要加上1;
Q4:多個文件函數之間的傳參比單個文件函數的傳參的難度要大太多了,寫到后面發現需要前面的參數,然后去修修改改真的真的好難TAT
A4:要寫一個框架,標出每個功能需要的參數,整理好了再敲代碼!!