CC++程序从⽂本⽂件中读取(保存)数据
:本⽂仅供初学者参阅,解惑
在C程序中:
与程序代码外的数据(⽂件)打交道,我们使⽤到流(stream)这个概念,实现进程的虚拟内存与⽂件之间的数据交换。
——⽂件流:C标准库提供了FILE(之所以命名为FILE,因为linux将所有机制都视为⽂件) ,FILE对象是⼀个包含了管理流所需的所有信息的结构,包括缓冲区信息、各种标记(如⽂件结束标记和错误标记)以及⽤于实际I/O的⽂件描述符等。
——输⼊流,输⼊流:数据从⽂件传送到内存的叫输⼊流,数据从内存传送到⽂件的叫输出流。
——打开⽂件:FILE对象通过调⽤函数创建的。如: FILE *fp, fp=fopen("filename","r"), 表⽰以只读的⽅式建⽴与filename相关的⽂件流;filename为当前⽬录下的相对路径名,r代表可读(打开⽂件的模式)。
⼀:读取
1:对⼀些有规范格式⽂件的读取,可使⽤标准库stdio.h下的函数,
函数原型为:int fscanf(FILE * stream, const char * format, [])
如读取⽂件(数据格式相对规范)
代码实现读取:
//test.c
//⽂件读取
#include<stdio.h>
int main()
{
/
/1:创建⽂件流,⽂件指针名=fopen(⽂件名,使⽤⽂件⽅式)打开失败则返回NULL;
FILE *fp=fopen("./","r"); //以⽂件为例
//2:检测⽂件是否打开成功;
if(!fp){
printf("打开失败!\n");
return -1; //返回异常
}
//3:
int num; //⽤来储存⼀个整型数据
char name[10], place[10]; //⽤来储存两个字符串数据
//抽象理解:
/
/理解⽂件位置含义:其表⽰已打开⽂件当前可读写字符的位置,其表⽰为⼀个到⽂件头的整数;
//fscanf在读取数据时可以这样理解:⽂件被打开后,它就成了⼀个⽆序字节流(⽔流),其会通过⼀个管道,流向被读取的⼀端;
//了解fscanf后知道,其遇到空格字符(空格,制表符),换⾏符,就会停⽌,这⾥的停⽌我们可以理解为:
//停下来为⽂件中两个不相关的数据块做⼀个分隔的操作,刚好适应了我们⼀般将空字符(包括换⾏符)作为两个数据之间的分隔的⾏为;
//我们只需理解管道的两端
//流进管道的⼀端的位置,就是⽂件的位置,表⽰已被读到的位置。
//流出管道⼀端,就是进程⽤来读取数据的⼀端,其可以对管道中已经做区分的数据进⾏读取。
//4:读取:
fscanf(fp,"%d%s%s",&num, name,place); //fscanf对流的格式化读取。
/
/注1:fscanf(fp,"%da%s%s",&num,name,place); 可以实现对数据:1a⼩刚河南;的准确读取,表⽰两个数据之间以a为界。
//注2:因为流是指针的性质,所以函数是将各数据块的⾸地址交给对应参数,所以num需进⾏&取地址操作,
//注3:因为name,place本⾝已表达地址,所以不⽤改变;
fscanf(fp,"\n");
//\n为控制字符,此时⽂件的位置到了第⼆⾏的开始;
//接着进⾏操作:fscanf(fp,"%d%s%s",&num, name,place);就可以继续读取第⼆⾏
//所以我们常常只需利⽤⼀个while语句就可以将整个⽂件读取到⼀个数据结构(进程)中
/*
while(!feof(fp)) //feof()检测⼀个⽂件是否结束,即到达⽂件尾,若结束,则返回⾮0值,否则返回0
{
fscanf(fp,"%d%s%s\n",&num, name,place);
}
*/
//检测读取结果
printf("%d %s %s\n",num, name, place);
//关闭流
fclose(fp);
return0;
}
程序运⾏结果:
2:从⽂件中读取整⾏数据(标准库stdio.h下的)
函数原型:char *fgets(char *str, int n, FILE *stream);
其从指定的流 stream 读取⼀⾏,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换⾏符时,或者到达⽂件末尾时,它会停⽌,遇到空格不停⽌;
例从⽂件中读取⼀⾏数据:
代码实现:
//test3.c
//⾏读取⽂件数据
#include<stdio.h>
#define maxlen 30
int main()
{
//创建⽂件流
FILE *fp=fopen("./","r");
//2:检测⽂件是否打开成功;
if(!fp){
printf("打开失败!\n");
return -1; //返回异常
}
char str[maxlen];//缓冲区,⽤来储存数据
//从⽂件中读取⼀⾏数据,储存到str开始的地址,最⼤长度为maxlen,然后下次读取从下⾏开始
/
/如果该⾏的数据长于maxlen-1,则只能返回⼀个不完整的⾏,并下次调⽤时从该处开始
fgets(str,maxlen,fp);
//检测结果
printf("%s\n",str);
//关闭流
fclose(fp);
return0;
}
运⾏结果:
⼆:保存
1:保存与读取往往相关联,保存格式决定了你读取的⽅式,使⽤函数可以进⾏指定格式的保存:
函数原型为:int fprintf( FILE *stream, const char *format, [ argument ]...)
假设保存⼀个⼈的个⼈信息到⽂件中:
/*test2.c */
//数据保存
#include<stdio.h>
int main()
{
//例⼀个⼈的信息
int num=1;
char name[10]="⼩明";
char place[10]="河南";
//建⽴与⽂件的流
FILE *fp=fopen("./","w");
//2:检测⽂件是否打开成功;
if(!fp){
printf("打开失败!\n");
return -1; //返回异常
}
//将数据格式化输出到指定⽂件流,int fprintf( FILE *stream, const char *format, [ argument ]...)
//注:此函数,是将format字符串写⼊到指定输出流中,format包括空格字符,⾮空格字符,说明符之中的⼀个或多个。如:fprintf(fp," "); 就是将空格输⼊到流中。 //可理解为进程借助流将数据打印(fprintf)到了⽂件中;
//将个⼈信息,写⼊指定流中,数据间以⼀个空格分隔,最后还写⼊换⾏符(控制字符)。
fprintf(fp,"%d %s %s\n",num, name,place);
//所以常常只要利⽤⼀个while语句就可以将讲⼀个表(链表,顺序表)按指定⾏格式写⼊输出流中
/*
while(!feof(fp)) //feof()检测⼀个⽂件是否结束,即到达⽂件尾,若结束,则返回⾮0值,否则返回0
{
fprintf(fp,"%d %s %s\n",num, name,place);
}
*/
//关闭流
fclose(fp);
return0;
}
运⾏结果:
2:写⼀个字符串到流中(fputs),函数原型:int fputs(const char *str, FILE *stream);
例:
//test4.c
//保存字符串
#include<stdio.h>
int main()
{
//1:创建⽂件流,⽂件指针名=fopen(⽂件名,使⽤⽂件⽅式)打开失败则返回NULL;
FILE *fp=fopen("./","a"); //以⽂件为例,a表⽰追加
//2:检测⽂件是否打开成功;
if(!fp){
printf("打开失败!\n");
return -1; //返回异常
}
//string
char string[20]="Facing the world";
//write string to the fstream
fputs(string,fp);
/
/关闭流
fclose(fp);
return0;
}
运⾏结果:
浅谈c++:
在c++中我们可以使⽤操作符<<, >>来进⾏流的读写操作,更加的⽅便和易于理解;
具体参考下列实例:
1:读取所⽰数据:
代码实现:
//c++⽂件读取
#include<iostream> //输⼊输出流
#include<fstream> //⽂件流
//using namespace std; //若使⽤该声明,则可以不⽤在使⽤的每个标准库的成员前加std::
int main()
{
//序号,年龄,年;
int num, age, year;
//姓名,地址
char name[20], place[20];
//c++的⽂件流,ifstream为输⼊⽂件流
std::ifstream fp;
//open为ifstream的成员函数,功能为打开⽂件,并将它与流关联
fp.open("./",std::ios::in); //ios::in表⽰读流的⽅式,表⽰打开模式。
//成员函数is_open检查流是否有关联⽂件,即打开成功与否,成功返回true,失败返回false
if(!fp.is_open()){
fprintf格式std::cout<<"打开⽂件失败!!\n";
return1; // 返回异常;
}
/
/读取数据
fp>>num>>year>>age>>name>>place; //使⽤操作符>>,将数据传输到对应的变量中
//检测
std::cout<<num<<":"<<name<<",age:"<<age<<",year:"<<year<<",live in:"<<place<<"\n"; //cout相当于printf //关闭流
fp.close();
return0;
}
运⾏结果:
2:往⽂件保存数据:
实例:保存⼀个⼈的具体信息到⽂件中
代码实现:
//c++数据保存
#include<iostream> //输⼊输出流
#include<fstream> //⽂件流
//using namespace std; //若使⽤该声明,则可以不⽤在使⽤的每个标准库的成员前加std::
int main()
{
//序号,年龄,年;
int num=3;
int age=20;
int year=1993;
//姓名,地址
char name[20]="⼩龙";
char place[20]="⼴元";
//c++的⽂件流,ofstream为输出⽂件流
std::ofstream fp;
//open为ofstream的成员函数,功能为打开⽂件,并将它与流关联
fp.open("./",std::ios::app); //ios::app表⽰每次写⼊是都追加到流尾,表⽰打开模式。
//成员函数is_open检查流是否有关联⽂件,即打开成功与否,成功返回true,失败返回false
if(!fp.is_open()){
std::cout<<"打开⽂件失败!!\n";
return1; // 返回异常;
}
//读取数据
fp<<num<<""<<year<<""<<age<<""<<name<<""<<place<<"\n"; //使⽤操作符<<,将各数据传输到流所关联的⽂件中 //关闭流
fp.close();
return0;
}
运⾏结果:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论