考试周把之前学的东西忘光光了,复习一下文件读写的操作
“文件名.c”表示C程序的源文件,
“文件名.cpp”表示C++程序的源文件,
“文件名.exe”表示可执行文件,
“文件名.txt”表示文本文件,
“文件名.jpg”表示一种图像的压缩数据文件,
“文件名.dat”可以表示自定义数据文件……
fputc和fgetc
int fputc(int c,FILE *pf);
int fgetc(FILE *pf);
代码示例
#include<iostream>
using namespace std;
int main()
{
int c=65;
FILE* pfile = fopen("E:\\new.txt", "rb+");
for (int i = 0; i < 26; i++)
if ((fputc(c, pfile))) { cout << "Written!\n"; c++; }
fseek(pfile, 0, SEEK_SET);//记得把文件的位置指针拉回开头
//还可以用rewind(pfile)代替
while (!feof(pfile))
{
c = fgetc(pfile);
printf("%c ", c);
}
if((fclose(pfile)==0))cout<<"\nClosed";
return 0;
}
fprintf和fscanf
int fscanf ( FILE *fp, char * format, ... );
int fprintf ( FILE *fp, char * format, ... );
代码示例(瞎写着玩的)
#include<iostream>
using namespace std;
int main()
{
FILE* pfile = fopen("E:\\new.txt", "r+");
int i = 0;
char name[25];
int num;
cin >> num;
while (num>0)
{
cin >> name;
fprintf(pfile, "%s %d", name, num);
cin >> num;
}
cin >> name;
num = 0;
fprintf(pfile, "%s %d\n", name, num);
rewind(pfile);
if ((fscanf(pfile, "%s", &name)) != 0)cout << "成功输入数据\n";
cout << name << endl;
rewind(pfile);
cout << "Show all\n";
while ((fscanf(pfile,"%s %d",&name,&num))!=EOF)
{
cout << name << " " << num << endl;
}
if ((fclose(pfile) == 0))cout << "Closed";
return 0;
}
fread fwrite
size_t fread(const void *ptr, size_t size, size_t
nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t
nmemb, FILE *stream);
代码示例
#include<iostream>
using namespace std;
struct User
{
char username[20];
char userID[5];
char password[20];
int phone;
};
void main()
{
User* user = (User*)malloc(sizeof(User));
FILE* fp = fopen("E:\\new.txt", "r+");
User users[5];
int i = 0;
while (i<5)
{
cin >> users[i].username >> users[i].userID >> users[i].password >> users[i].phone;
fwrite(&users[i], sizeof(User), 1, fp);
i++;
}
cout << "本次输入的用户信息:\n";
rewind(fp);
fread(user, sizeof(User), 1, fp);
while (!feof(fp))
{
cout << user->username << " " << user->userID << " " << user->phone << " " << user->password << endl;
fread(user, sizeof(User), 1, fp);
}
}
写进txt文件烫烫烫烫了,fwrite可能是把整个字符串数组都写进去了,用fscanf和fprintf代替可以解决。
int fseek(FILE *stream, long offset, int whence);
该函数的功能是将文件位置指针指向位置
whence + offset
,参数
whence
指出参
考位置,其取值可以为
SEEK_SET
(系统定义的值为
0
的宏,表示文件头),
SEEK_CUR
(系统定义的值为
1
的宏,表示当前位置)或
SEEK_END
(系统定义的值
为
2
的宏,表示文件末尾),参数
offset
偏移参考位置的字节数,它可以为正值(
向后偏移)或负值(向前偏移)。例如,
fseek(pfile, 10, SEEK_SET); //
位置指针移至第
11
个字节处
fseek(pfile, 10, SEEK_CUR); //
从当前位置向后移动
10
个字节
fseek(pfile, -10, SEEK_END);//
移至倒数第
10
个字节处
返回文件指针位置的函数
long ftell(FILE *stream);
把文件指针拉回文件头部的库函数
void rewind(FILE *stream);
基于字符串的输入输出
int sscanf(char *buffer, const char *format, ...);
int sprintf(const char *buffer, const char *format, ...);
这两个库函数的功能是从程序中的字符串中获得数据/
把程序结果保存到字符串中。
这两个库函数的返回值为参数的个数/
字符串长度,其他特征与标准输入
/
输出库函数类似。
int x;
char str1[20];
scanf("%d", &x);
sprintf(str1, "%d", x); //int型变量x的值转换成字符串存入str1中
char str2[20] = "233hellonju";
char s[6];
sscanf(str2, “%d%5s”, &x, s);//从str2中 x获得233,s获得hello 66
综合应用
假定无线传感器网络采集的火山口温度值存于数据文件vol.dat
中,
编程对异常采集数据进行预处理(比如将温度值为
0
的采集数据用前后相邻
两个采集数据的平均值代替,最后一个温度值若为
0
用前一个数代替)。
[分析
]
可以采用随机数生成的方式模拟数据采集,以便向所创建的文件
中写入原始数据
#include<iostream>
#include<stdlib.h>
#include<time.h>
#define N 10
using namespace std;
void DataGenerator(FILE** fpp);
void PreTreat();
int main()
{
FILE* fp;
const char* fname = "E:\\newdata.dat";
if ((fp = fopen(fname, "wb")) == NULL)
{
cout << "Can't open this file ! \n";
exit(0);
}
DataGenerator(&fp);
fclose(fp);
cout << "输入原始数据到控制台:\n";
FILE* pf = fopen(fname, "rb");
float t;
while (!feof(pf))
{
if (fread(&t, sizeof(t), 1, pf) != 0)
cout << t << endl;
}
fclose(pf);
PreTreat();
return 0;
}
void DataGenerator(FILE** fpp)
{
srand(time(0));
for (int i = 0; i < N; i++)
{
float j = 100 * rand() / RAND_MAX;//生成随机数,模拟数据采集
fwrite(&j, sizeof(j), 1, *fpp);//写入文件
float k = 0;
fwrite(&k, sizeof(k), 1, *fpp);//故意间隔写入异常数据0
}
}
void PreTreat()
{
FILE* pfile = fopen("E:\\newdata.dat","r+b");
float t, tNext, tPre;
fread(&tPre, sizeof(t), 1, pfile);//读取第一个数据作为前一个数据
fread(&t, sizeof(t), 1, pfile);//读取第二个数据作为当前待处理数据
while (!feof(pfile))
{
if (fread(&tNext, sizeof(t), 1, pfile) != 0)//读取下一个数据
{
if (t <= 0.1) {
t = (tPre + tNext) / 2;
fseek(pfile, -2*(long)(sizeof(t)), SEEK_CUR);
//位置指针往回移至待处理数据前端
fwrite(&t, sizeof(t), 1, pfile);
fseek(pfile, sizeof(t), SEEK_CUR);
//恢复位置指针至下一个数据前端
}
tPre = t;//当前数据处理完作为下一次处理的前一数
t = tNext;//下一个数据作为待处理数据
}
}
fseek(pfile, -1*(long)sizeof(t), SEEK_CUR);
fwrite(&tPre, sizeof(t), 1, pfile);//修改最后一个数据
cout << "\n预处理后的数据:\n";
rewind(pfile);
while (!feof(pfile))
{
if (fread(&t, sizeof(t), 1, pfile) != 0)
cout << t << endl;
}
fclose(pfile);
}