(此图来自王桂林课程系列)
函数fseek:
注意:文件指针指向文件/流。位置指针指向文件内部的字节位置,随着文件的读取会移动,
文件指针如果不重新赋值将不会改变或指向别的文件。
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
利用此函数可以指定读取文件中的第n个数据:fseek();先将指针移到需要读取数据的
位置(比如说在学生信息表中需要读取第n个学生的信息 fseek(fp,(long)(n*sizeof(Student)),0)从
第0个位置移动到第n个信息的位置,再使用fread(&item,sizeof(Student),1,fp);就读取到了相应的数据
Student item;
FILE *fp;
fp=open(..........);
fseek(fp,(long)(n*sizeof(Student)),0)
read(&item,sizeof(Student),1,fp);
fclose(fp);
C语言的文件读取相对麻烦 (SEEK_SET:文件开始点) (SEEK_END:文件末尾)
第一种:先读取文件大小,通过文件大小来定义动态数组作为读取文件信息的存储空间,单个读取字符
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
int main()
{
long size;
int i=0;
FILE *fp;
fp=fopen("D:\\Qt\\nicejob.txt","r+");
fseek (fp, 0, SEEK_END); //将文件指针移动文件结尾,但是这种用法通常是在二进制文件的处理中否则,容易发生混乱
size=ftell (fp); //求出当前文件指针距离文件开始的字节数
cout<<size<<endl;
fclose (fp);
//前面先读取到了文件的大小
//我们可以通过获得的size来开辟动态数组读取并存放文件信息并输出
fp=fopen("D:\\Qt\\nicejob.txt","r+");
if(fp==NULL)
{
printf("error");
return -1;
}
char *str;
str=(char*)malloc(sizeof(char)*size);
while(!feof(fp))//每次读取一个字符
{
fscanf(fp,"%c",&str[i]);
printf("%c",str[i]);
i++;
}
fclose(fp);
}
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <vector>
using namespace std;
int main()
{
FILE *fp=NULL;
fp=fopen("D:\\Qt\\nicejob.txt","r+");
if(fp==NULL)
{
printf("error");
return -1;
}
int lineCount=0;
char buf[1024];
while(fgets(buf,1024,fp)!=NULL)//将数据读取并存到buf中 一行一行的读取
lineCount++;
rewind(fp);//这里是将文件位置指针从新置于文件头
char **p=(char**)malloc((lineCount+1)*sizeof(char*));//定义一个指针数组
char **pt=p;
while(fgets(buf,1024,fp)!=NULL)
{
int len = strlen(buf);
*pt = (char*)malloc(len+1);
strcpy(*pt,buf);//把读取到的数据复制到pt数组中
pt++;
}
*pt=NULL;
while(*p)
{
printf("%s",*p++);
}
fclose(fp);
return 0;
}
C++方法:
通过定义向量来存储信息,相对来说简洁了许多
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <vector>
using namespace std;
int main()
{
FILE *fp=fopen("D:\\Qt\\nicejob.txt","r+");
if(fp==NULL)
{
return -1;
}
vector<string> vs;//生成string类型的变量vs
char buf[1024];
while(fgets(buf,1024,fp)!=NULL)//一行一行的读取信息
{
vs.push_back(buf);//将读取到的信息添加到buf的信息结尾处
// cout<<buf<<endl;
}
for(int i=0;i<vs.size();i++)
{
cout<<vs[i];
}
fclose(fp);
}
下面是文件内的内容:
关于 feof 的问题 :
feof 这个函数,是去读标志位判断文件是否结束的。即在读到文件结尾的时候 再去读一次,标志位才会置位,此时再来作判断文件处理结束状态,文件到结尾。如果 用于打印,则会出现多打一次的的现象。
#include <stdio.h>
int main() {
FILE* fp = fopen("text.txt","w+");
if(fp == NULL)
return -1;
fputs("aaaaaaaaaaaaaaaaaaaaaaaaaaa\n",fp);
fputs("bbbbbbbbbbbbbbbbbbbbbbbbbbb\n",fp);
fputs("ccccccccccccccccccccccccccc\n",fp);
fputs("ddddddddddddddddddddddddddd\n",fp);
fputs("eeeeeeeeeeeeeeeeeeeeeeeeeee\n",fp);
fputs("fffffffffffffffffffffffffff",fp);
rewind(fp);
char buf[30] = {0};
while(fgets(buf,30,fp)&&!feof(fp))//最取最后一行的时候 feof 己经认为空了。
{ printf("%s",buf); } fclose(fp);//这样的话就少读了一行
return 0;
}
如果最后一行,没有行‘\n’的话则少读一行。 Linux 中无论是gedit 还是vim 系统会自动在末行添加\n标志。Windows当中要注 意系统不会自动添加\n,最好用返回值来判断,是否读到结尾。
写入:
#include <iostream>
using namespace std;
int main()
{
char *buf="abcdefg er\nsfsdf";
FILE *fp=fopen("data.txt","w+");
fprintf(fp,"%s",buf);
fclose(fp);
return 0;
}
读取:
#include <stdio.h>
int main()
{
FILE *fp = fopen("data.txt","r");
if(fp == NULL)
{
printf("fopen error\n");
return -1;
}
char buf[1024];
while(fgets(buf,1024,fp) != NULL)
{
printf("%s",buf);
}
fclose(fp);
return 0;
}