3 回答

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

TA貢獻1789條經驗 獲得超10個贊
首先是最簡單的讀寫一個字符的函數fputc和fgetc,在這個基礎上又出現了putw和getw、fgets和fputs,此外還說過格式化讀寫函數fprintf和fscanf函數。
從原理上來說,只要fputc和fgetc函數基本就可以完成數據的讀寫操作了,但是在實際的使用中會遇到諸多不便,因此上面那一大堆函數就冒出來了(其實也不多)。上面函數中最方便的就是格式化讀寫函數fprintf和fscanf了,因為可以一行行的進行讀取,但是有個問題就是這兩位老人家動作比較慢,fprintf在寫文件的時候要把二進制形式表示的數據轉換為ASCII碼形式,fscanf在讀文件的時候又要將ASCII碼轉換為二進制的形式。
好不容易出來個好用的函數,竟然是個慢性子,聰明的你現在也許就在想了:那能不能不轉換,直接讀寫二進制的數據呢?答案就是fread和fwrite,在需要頻繁進行數據讀寫的時候,使用這兩個函數將大大提升效率。
fread和fwrite函數的定義
fread(pBuffer,size,count,pFile);
fwrite(pBuffer,size,count,pFile);
要讀寫一個數據塊的話,無論是讀還是寫,都需要指定一個起始地址,讀的話從這個起始地址讀,寫的話從這個起始地址寫,上面函數定義中的第一個參數pBuffer就是用于指定這個起始地址,size讀寫的字節數,count則指定讀寫多少個size大小的數據,pFile是文件結構指針。
fread和fwrite函數使用示例
說到數據塊我們自然會想到結構體,如果一個文件中保存的是一個個結構體信息,那每一個結構體信息就可以看做一個數據塊了。這里直接用前面文章中我們一直使用的學生成績信息的結構體:
C語言: 知蟻博客
struct student
{
int nID; //學號
char chName[20]; //姓名
float fScores[3]; //3門課的成績
};
實例程序有點小復雜的,首先我們自己新建一個txt文件,也就是ASCII文件啦,然后寫上一些數據,如下:
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方式打開這個文件,通過fscanf函數讀取里面的數據,然后通過fwrite寫入到新的二進制格式的文件中,這樣我們就得到了一個保存上面信息的二進制格式的文件了,下面就是通過fread函數進行數據的讀取了。(記?。篺read和fwrite一般用于二進制文件的輸入輸出,ASCII文件還是不要考慮了)。
C++語言: 知蟻博客
#include "stdio.h"
struct student
{
int nID; //學號
char chName[20]; //姓名
float fScores[3]; //3門課的成績
};
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;
}
//二進制文件打開文件 用于寫入
pWrite=fopen("stu_scores_bin.txt","wb");
if(NULL == pWrite)
{
fclose(pRead);
return;
}
//fscanf讀取數據,fwrite寫入數據
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)); //清空數據
//二進制文件打開文件 用于讀取
pRead=fopen("stu_scores_bin.txt","rb");
if(NULL == pRead)
{
printf("open file stu_scores_bin.txt failed");
return;
}
//下面有兩種fread的讀數據方式,將下面的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
//因為事先知道有4條信息,因此可以直接讀取四條信息
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讀取的時候,我們既可以一條條的讀取,也可以一次讀入多條,這就是為什么參數中有size和count的原因
- 3 回答
- 0 關注
- 973 瀏覽
添加回答
舉報