文件头指针返回值就是存储了从文件读取了学生信息的链表的头指针,可以使用这个指针访问读取到的学生信息。
测试代码如下:
参考链接:
#include <stdio.h>
#include <stdlib.h>
struct student{ // 存储学生信息的结构
int num; // 这个应该是学号
char name[20]; // 姓名
char sex; // 性别
int age; // 年龄
float score; // 成绩
struct student *link; // 指向下个学生信息结构的指针
};
struct student *load(){ // 从文件读取学生信息存入链表中
struct student *head,*p,*q;
FILE * fp;
// https://www.runoob.com/cprogramming/c-file-io.html
if((fp=fopen("stud.dat","rb"))==NULL){ // 以二进制只读模式打开文件stud.dat
printf("can't open file stud.dat\n");
getchar();
exit(0);
}
head=NULL;
// 申请一个 学生结构的内存空间,把这个结构的地址赋值给结构指针q
q=(struct student *)malloc(sizeof(struct student));
// 循环从文件中读取学生信息,直到文件结束
// 从文件读取一个学生信息结构长度的数据, 存入结构指针p指向的内存中
while (fread(q,sizeof(struct student),1,fp)==1){
q->link=NULL; // q指针的下一个节点赋值为NULL
if(head==NULL){ // 如果链表头指针为NULL,则将当前结构指针p赋值给链表头指针 head
head=q;
p=head; // 用p来存储头指针,以便使用p来创建后续链表
}else{ // 如果头指针不为NULL,则将 前一个节点的下一个节点赋值为当前结构指针p,将链表前后连接起来
p->link = q;
p=p->link; // p节点指向当前节点
}
// 为下一个学生信息申请一块内存
q=(struct student*)malloc(sizeof(struct student));
}
free(q); // 释放最后申请的一块内存
fclose(fp); // 关闭文件
return head; // 返回链表头指针
}
int main(void){
struct student s;
int num,i;
FILE * fp;
if((fp=fopen("stud.dat","wb"))==NULL){ // 以二进制只写模式打印文件stud.dat
printf("can't open file stud.dat\n");
getchar();
exit(0);
}
// 获取要输入学生信息的个数
printf("请输入要输入的学生信息的个数:");
scanf("%d",&num);
// 从输入读取num个学生信息,写入文件stud.dat中
for(i=0;i<num;i++){
printf("\n请输入第%d个学生学号:",i+1);
scanf("%d",&s.num);
printf("请输入第%d个学生姓名:",i+1);
scanf("%s",s.name);
fflush(stdin);
printf("请输入第%d个学生性别:",i+1);
scanf("%c",&s.sex);
printf("请输入第%d个学生年龄:",i+1);
scanf("%d",&s.age);
printf("请输入第%d个学生成绩:",i+1);
scanf("%f",&s.score);
fwrite(&s,sizeof(struct student),1,fp);
}
fclose(fp);
struct student * phead = load(); // 从文件中读取学生信息,并返回链表 头结点,存入指针phead中
struct student * temp;
printf("\n从文件读取的信息如下:\n");
// 从链表头结点 开始,将链表中读取到的学生信息显示出来
while(phead!=NULL){
printf("学号:%d ,姓名:%s, 性别:%s, 年龄:%d,成绩:%f\n",phead->num,phead->name,phead->sex=='m'?"男":"女",phead->age,phead->score);
temp=phead;
phead=phead->link;
free(temp); // 释放前一个节点的内存
}
fclose(fp); // 关闭文件
return 0;
}
核心,是在目录中,查找文件,并保存在容器中
细节不再讲,可以参考下面的代码
//-----------------------------------------------------------
//
// 函数名称:FindFileInDir
//
// 参 数:
// - BOOL bSize 是否判断文件大小
//
// - CString fileExtention 文件扩展名,不包括‘.’
//
// - CString filePath 文件所在的父目录
//
// - std::vector<CString> &pageVector 保存指定文件的容器
//
// 返 回:void
//
// 函数作用:查找目录filePath下,扩展名为FindFileInDir的所有文件
//
// 修改日期:2012年9月17日 By YuJian
//
//-----------------------------------------------------------
void FindFileInDir(BOOL bSize, CString fileExtention, CString filePath, std::vector<CString>& pageVector)
{
std::vector <CString> directoryPath;
CString subfilePathtemp;
CString subFilePath;
WIN32_FIND_DATA fd;
ZeroMemory(&fd, sizeof(WIN32_FIND_DATA));
HANDLE hSearch;
if (filePath.Right(1) != _T("\\"))
{
filePath += _T("\\");
}
filePath += _T("*");
hSearch = ::FindFirstFile(filePath, &fd);
if (INVALID_HANDLE_VALUE == hSearch)
{
AfxMessageBox(L"请正确选择文件夹");
return;
}
subFilePath = filePath.Left(filePath.GetLength() - 1);
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !(fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) && !(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) && _tcscmp((const TCHAR*)&fd.cFileName, L".") && _tcscmp((const TCHAR*)&fd.cFileName, L"..") && _tcscmp((const TCHAR*)&fd.cFileName, L"RECYCLER") && _tcscmp((const TCHAR*)&fd.cFileName, L"System Volume Information")) //文件夹
{
subfilePathtemp = subFilePath + fd.cFileName;;
directoryPath.push_back(subfilePathtemp);// 将目录放大局部容器变量中
}
else {
subfilePathtemp = fd.cFileName;
int dotPosition = subfilePathtemp.ReverseFind(L'.');
subfilePathtemp = subfilePathtemp.Right(subfilePathtemp.GetLength() - dotPosition - 1);
if (subfilePathtemp.Compare(fileExtention) == 0)
{
//subfilePathtemp=subFilePath+fd.cFileName;
//pageVector.push_back(subfilePathtemp); // 将所查到文件放入全局容器变量中, 这样遍历完所有文件夹后,所有的文件路径都存放在了全局容器中
if (!bSize)
pageVector.push_back(subFilePath+fd.cFileName);
else
if (fd.nFileSizeLow == 466 || fd.nFileSizeLow == 226)
pageVector.push_back(fd.cFileName);
}
}
BOOL bFinished = FALSE;
while (!bFinished)
{
if (FindNextFile(hSearch, &fd))
{
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !(fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) && !(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) && _tcscmp((const TCHAR*)&fd.cFileName, L".") && _tcscmp((const TCHAR*)&fd.cFileName, L"..") && _tcscmp((const TCHAR*)&fd.cFileName, L"RECYCLER") && _tcscmp((const TCHAR*)&fd.cFileName, L"System Volume Information")) //文件夹
{
subfilePathtemp = subFilePath + fd.cFileName;;
directoryPath.push_back(subfilePathtemp);
}
else {
subfilePathtemp = fd.cFileName;
int dotPosition = subfilePathtemp.ReverseFind(L'.');
subfilePathtemp = subfilePathtemp.Right(subfilePathtemp.GetLength() - dotPosition - 1);
if (subfilePathtemp.Compare(fileExtention) == 0)
{
pageVector.push_back(subFilePath + fd.cFileName);
//if (!bSize)
// pageVector.push_back(fd.cFileName);
//else
// if (fd.nFileSizeLow == 466 || fd.nFileSizeLow == 226) //闪电图的大小
// pageVector.push_back(fd.cFileName);
}
}
}
else {
if (GetLastError() == ERROR_NO_MORE_FILES) //正常结束
{
bFinished = TRUE;
}
else {
bFinished = TRUE;
}
}
}
FindClose(hSearch); //关闭查找
//for (int i = 0; i < directoryPath.size(); i++) //对每一个路径,递归调用
//{
// FindFileInDir(bSize, fileExtention, directoryPath.at(i), pageVector);
//}
}