今天帮同学写一个C风格的文件读写程序,发现这块儿有些遗忘了,现在记下来。
程序的要求是从一个保存整数的文本里读取整数,如果相邻位置有重复的整数,重复的只算一次。把读取的整数存到一个文件里,对应的序号(从1开始)存到另外一个文件里。
在VS中直接使用fopen() 是不能通过的,需要在工程属性里,
预处理器定义栏里,添加 _CRT_SECURE_NO_WARNINGS
这里的CRT是C语言运行时库。
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main()
{
FILE *fp;
FILE *fdata;
FILE* fpos;
fp = fopen("F:\\Ctest\\cFile\\5536.txt", "r");
fdata = fopen("data.txt", "w+");
fpos = fopen("pos.txt", "w+");
int fir, sec, iter = 1;
if (fp && fdata && fpos)
{
fscanf(fp, "%d", &fir); //读入第一个数
fprintf(fdata, "%d\n", fir);
fprintf(fpos, "%d\n", iter);
while (!feof(fp))
{
fscanf(fp, "%d", &sec); //读入新的一个数
++iter; //每读入一个数,位置更新
if (sec == fir) //如果重复,一直读入到不重复为止
{
if (!feof(fp)) //防止最后一个数据和前边的相同
{
do
{
fscanf(fp, "%d", &sec);
++iter;
} while ((sec == fir) && (!feof(fp))); //如果重复,重新读入到不同为止
fir = sec;
fprintf(fdata, "%d\n", fir);
fprintf(fpos, "%d\n", iter);
}
}
else //不重复,写入到文件中
{
fir = sec;
fprintf(fdata, "%d\n", fir);
fprintf(fpos, "%d\n", iter);
}
}
}
else
{
printf("file open filed!");
}
fclose(fp);
fclose(fdata);
fclose(fpos);
return 0;
}
三个文件的中的内容如下:
左边是原始数据文件,中间的取出的去掉多余的连续位置重复的数据文件data.txt,右边是对应的位置文件pos.txt文件。
说到C文件的读写,就得讲讲open() 与 fopen() 函数的区别,open() 是低级的IO,用于非缓冲文件系统。fopen() 是高级IO,会开辟一个缓冲区,是缓冲文件系统。open() 函数返回的是一个整数句柄,fopen() 返回的则是一个文件指针。fopen() 的标准库里的函数,更具有移植性。fopen()打开文件,使用 f打头的读写函数来读写和操作:fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind.
fscanf() 按“%d” 读入时,会忽略此时文件指针后的空白字符(刚打开文件,文件指针指向文件的开头), 直到指向的是整数(如果前边有负号“-”,可以成功读入负数)。如果此时文件指针fp指向的是非数字,fscanf() 将不能成功将整数读入给后边的整数fir,并且fscanf()返回值是0,并且文件指针fp的指向不变。
fscanf() 成功的读入了整数之后,会自动的移动到整数的下一个位置,同C++中流的思想一样。
在文件中移动文件指针的函数是:
int fseek ( FILE * stream, long int offset, int origin );
移动的位置有三个基准点,分别是文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END)), offset表示偏移量(正在基准的后边,负在基准的前边)。
假如现在一个文本文件hello.txt的最后是一个7位数的数字, 我想读出最后的三位,那么可以这样做:
FILE* fp = fopen("hello.txt", "r"); //打开文件
fseek(fp,-3,SEEK_END); //移动文件指针到文件尾的前3个位置
int i; //用来保存读取出来的整数值
fscanf(fp,"%d", &i); //读取