3 回答

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超6個(gè)贊
fread(&stu[i],sizeof(struct student),1,fp);
二進(jìn)制讀取,每次讀取指定字節(jié)數(shù)
你的文件是文本方式的,讀出來(lái)就錯(cuò)了
float score[3];//float類型是4個(gè)byte,score[3]就是12個(gè)byte
比如----------------------------------------------------
200501 zhao 78 79 79
結(jié)構(gòu)中定義num是long型,占4個(gè)字節(jié)
這里200501是字符型,占6個(gè)字節(jié)
用fread()讀,num就對(duì)應(yīng)"2005"(存儲(chǔ)為32 30 30 35)
可以用Ultra-edit查看文本文件的二進(jìn)制

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超10個(gè)贊
首先是最簡(jiǎn)單的讀寫一個(gè)字符的函數(shù)fputc和fgetc,在這個(gè)基礎(chǔ)上又出現(xiàn)了putw和getw、fgets和fputs,此外還說(shuō)過(guò)格式化讀寫函數(shù)fprintf和fscanf函數(shù)。
從原理上來(lái)說(shuō),只要fputc和fgetc函數(shù)基本就可以完成數(shù)據(jù)的讀寫操作了,但是在實(shí)際的使用中會(huì)遇到諸多不便,因此上面那一大堆函數(shù)就冒出來(lái)了(其實(shí)也不多)。上面函數(shù)中最方便的就是格式化讀寫函數(shù)fprintf和fscanf了,因?yàn)榭梢砸恍行械倪M(jìn)行讀取,但是有個(gè)問(wèn)題就是這兩位老人家動(dòng)作比較慢,fprintf在寫文件的時(shí)候要把二進(jìn)制形式表示的數(shù)據(jù)轉(zhuǎn)換為ASCII碼形式,fscanf在讀文件的時(shí)候又要將ASCII碼轉(zhuǎn)換為二進(jìn)制的形式。
好不容易出來(lái)個(gè)好用的函數(shù),竟然是個(gè)慢性子,聰明的你現(xiàn)在也許就在想了:那能不能不轉(zhuǎn)換,直接讀寫二進(jìn)制的數(shù)據(jù)呢?答案就是fread和fwrite,在需要頻繁進(jìn)行數(shù)據(jù)讀寫的時(shí)候,使用這兩個(gè)函數(shù)將大大提升效率。
fread和fwrite函數(shù)的定義
fread(pBuffer,size,count,pFile);
fwrite(pBuffer,size,count,pFile);
要讀寫一個(gè)數(shù)據(jù)塊的話,無(wú)論是讀還是寫,都需要指定一個(gè)起始地址,讀的話從這個(gè)起始地址讀,寫的話從這個(gè)起始地址寫,上面函數(shù)定義中的第一個(gè)參數(shù)pBuffer就是用于指定這個(gè)起始地址,size讀寫的字節(jié)數(shù),count則指定讀寫多少個(gè)size大小的數(shù)據(jù),pFile是文件結(jié)構(gòu)指針。
fread和fwrite函數(shù)使用示例
說(shuō)到數(shù)據(jù)塊我們自然會(huì)想到結(jié)構(gòu)體,如果一個(gè)文件中保存的是一個(gè)個(gè)結(jié)構(gòu)體信息,那每一個(gè)結(jié)構(gòu)體信息就可以看做一個(gè)數(shù)據(jù)塊了。這里直接用前面文章中我們一直使用的學(xué)生成績(jī)信息的結(jié)構(gòu)體:
C語(yǔ)言: 知蟻博客
struct student
{
int nID; //學(xué)號(hào)
char chName[20]; //姓名
float fScores[3]; //3門課的成績(jī)
};
實(shí)例程序有點(diǎn)小復(fù)雜的,首先我們自己新建一個(gè)txt文件,也就是ASCII文件啦,然后寫上一些數(shù)據(jù),如下:
1 zhangsan 78.0 79.0 80.0
2 lisi 79.0 77.0 78.0
3 wangwu 90.0 97.0 78.0
4 zhaokai 56.0 57.0 58.0
我們先用ASCII方式打開這個(gè)文件,通過(guò)fscanf函數(shù)讀取里面的數(shù)據(jù),然后通過(guò)fwrite寫入到新的二進(jìn)制格式的文件中,這樣我們就得到了一個(gè)保存上面信息的二進(jìn)制格式的文件了,下面就是通過(guò)fread函數(shù)進(jìn)行數(shù)據(jù)的讀取了。(記?。篺read和fwrite一般用于二進(jìn)制文件的輸入輸出,ASCII文件還是不要考慮了)。
C++語(yǔ)言: 知蟻博客
#include "stdio.h"
struct student
{
int nID; //學(xué)號(hào)
char chName[20]; //姓名
float fScores[3]; //3門課的成績(jī)
};
void main()
{
FILE *pRead,*pWrite;
struct student tStu[4];
struct student *ptStu = NULL;
int nCount = 0;
//ASCII方式打開文件 用于讀入
pRead=fopen("stu_scores.txt","r");
if(NULL == pRead)
{
return;
}
//二進(jìn)制文件打開文件 用于寫入
pWrite=fopen("stu_scores_bin.txt","wb");
if(NULL == pWrite)
{
fclose(pRead);
return;
}
//fscanf讀取數(shù)據(jù),fwrite寫入數(shù)據(jù)
ptStu = tStu;
while(!feof(pRead))
{
fscanf(pRead,"%d %s %f %f %f\n",&ptStu->nID,ptStu->chName,&ptStu->fScores[0],&ptStu->fScores[1],&ptStu->fScores[2]);
fwrite(ptStu,sizeof(struct student),1,pWrite);
printf("%d %s %.1f %.1f %.1f\n",ptStu->nID,ptStu->chName,ptStu->fScores[0],ptStu->fScores[1],ptStu->fScores[2]);
ptStu++;
}
fclose(pRead);
fclose(pWrite);
memset(tStu,0×00,sizeof(tStu)); //清空數(shù)據(jù)
//二進(jìn)制文件打開文件 用于讀取
pRead=fopen("stu_scores_bin.txt","rb");
if(NULL == pRead)
{
printf("open file stu_scores_bin.txt failed");
return;
}
//下面有兩種fread的讀數(shù)據(jù)方式,將下面的1換成0,則使用第二種方式
#if 1
//一條條的讀取
ptStu = tStu;
nCount = fread(ptStu,sizeof(struct student),1,pRead);
while(nCount>0)
{
printf("%d %s %.1f %.1f %.1f\n",ptStu->nID,ptStu->chName,ptStu->fScores[0],ptStu->fScores[1],ptStu->fScores[2]);
ptStu++;
nCount = fread(ptStu,sizeof(struct student),1,pRead);
}
#else
//因?yàn)槭孪戎烙?條信息,因此可以直接讀取四條信息
fread(tStu,sizeof(struct student),4,pRead);
for(nCount=0; nCount<4; nCount++)
{
printf("%d %s %.1f %.1f %.1f\n",tStu[nCount].nID,tStu[nCount].chName,tStu[nCount].fScores[0],tStu[nCount].fScores[1],tStu[nCount].fScores[2]);
}
#endif
fclose(pRead);
}
上面用fread讀取的時(shí)候,我們既可以一條條的讀取,也可以一次讀入多條,這就是為什么參數(shù)中有size和count的原因
- 3 回答
- 0 關(guān)注
- 978 瀏覽
添加回答
舉報(bào)