总结一下几个文件操作注意点。
- 新打开文件时注意括号
注意 赋值= 的优先级低于 比较==
一定要
(fp = fopen("in.txt", "r")) == NULL
- 注意一些惯用操作
FILE* fp;
if ((fp = fopen("in.txt", "r")) == NULL) printf("Open Fail.");
else {
for(i = 0; i <= 99; i++){
fscanf(fp, "%d", &(a[j++]));
}
}
fclose(fp);
- 明确六种打开模式
r: 打开一个已有文件,只能读,位置指针默认在开头
r+:打开一个已有文件,可以读写,位置指针默认在开头
a: 打开一个已有文件,只能写,位置指针默认在结尾
a+:打开一个已有文件,可以读写,位置指针默认在结尾
w: 新建一个文件,只能写,位置指针默认在开头。(新建时覆盖原有文件)
w+:新建一个文件,可以读写,位置指针默认在开头。(新建时覆盖原有文件)
题目-小内存大数据排序
假设内存中最多可以存100个正整数,实现一个排序方法,可以对包含1000个正整数的磁盘文件进行排序。这里假设排序操作只能在内存中进行。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h> //与文件删除的查错有关的库
#define MAXN 99999
void ReadFile(int* a, int num);
void QuickSort(int* a, int low, int high);
void GuiBing(FILE** fparr, int* a);
FILE* OutputFile(int* a, int num);
void Remove1(FILE** fparr);
int main(void)
{
int i;
int a[100];
FILE* fparr[10];
for (i = 0; i <= 9; i++) {
ReadFile(a, i);
QuickSort(a, 0, 99);
fparr[i] = OutputFile(a, i);
}
GuiBing(fparr, a);
Remove1(fparr);
return 0;
}
void GuiBing(FILE** fparr, int* a)
{
FILE* fpout;
if ((fpout = fopen("out.txt", "w")) == NULL)
printf("Open out.txt fail.");
int i, amin, cnt = 0;
for (i = 0; i <= 9; i++) {//读入每组第一个数
fscanf(fparr[i], "%d", &(a[i]));
}
while (cnt != 1000) {
amin = a[0];
for (i = 1; i <= 9; i++) {//找到a中最小的
amin = min(a[i], amin);
}
for (i = 0; i <= 9; i++) {
if (a[i] == amin) {
fprintf(fpout, "%d ", amin); cnt++;
if (!feof(fparr[i])) { fscanf(fparr[i], "%d ", &(a[i])); }
else { a[i] = MAXN; }
break;
}
}
}
fclose(fpout);
return;
}
void ReadFile(int* a, int num)//num是第几组(从0开始)
{
int i = 0, j = 0;
FILE* fp;
if ((fp = fopen("in.txt", "r")) == NULL) printf("Open Fail.");
else {
for(i = 0; i <= 999; i++){
if (i >= num * 10 && i <= num * 10 + 99) fscanf(fp, "%d", &(a[j++]));
}
}
fclose(fp);
return;
}
FILE* OutputFile(int* a, int num)
{
int i = 0;
FILE* fp = NULL;
if (num == 0) { if ((fp = fopen("out0.txt", "w+")) == NULL) printf("Output Fail."); }
if (num == 1) { if ((fp = fopen("out1.txt", "w+")) == NULL) printf("Output Fail."); }
if (num == 2) { if ((fp = fopen("out2.txt", "w+")) == NULL) printf("Output Fail."); }
if (num == 3) { if ((fp = fopen("out3.txt", "w+")) == NULL) printf("Output Fail."); }
if (num == 4) { if ((fp = fopen("out4.txt", "w+")) == NULL) printf("Output Fail."); }
if (num == 5) { if ((fp = fopen("out5.txt", "w+")) == NULL) printf("Output Fail."); }
if (num == 6) { if ((fp = fopen("out6.txt", "w+")) == NULL) printf("Output Fail."); }
if (num == 7) { if ((fp = fopen("out7.txt", "w+")) == NULL) printf("Output Fail."); }
if (num == 8) { if ((fp = fopen("out8.txt", "w+")) == NULL) printf("Output Fail."); }
if (num == 9) { if ((fp = fopen("out9.txt", "w+")) == NULL) printf("Output Fail."); }
for(i = 0; i <= 99; i++){
fprintf(fp, "%d ", a[i]);
}
//fclose(fp);
rewind(fp); //可以rewind文件指针,来让文件位置指针回到开头
return fp;
}
void Remove1(FILE** fparr)
{
int err0;
fclose(fparr[0]);
err0 = remove("out0.txt"); //文件删除函数
if (err0 == -1) perror("remove"); //这是一种查错方法,若删除失败可以知道原因
fclose(fparr[1]); remove("out1.txt"); //与手动删除相同,没关闭的文件是不能删除的
fclose(fparr[2]); remove("out2.txt"); //另外,只读文件也不能删除
fclose(fparr[3]); remove("out3.txt");
fclose(fparr[4]); remove("out4.txt");
fclose(fparr[5]); remove("out5.txt");
fclose(fparr[6]); remove("out6.txt");
fclose(fparr[7]); remove("out7.txt");
fclose(fparr[8]); remove("out8.txt");
fclose(fparr[9]); remove("out9.txt");
}
void QuickSort(int* a, int low, int high)
{
int i = low, j = high;
int key = a[low];
if (low >= high)return;
while (i < j) {
while (i < j&&a[j] >= key) j--;
a[i] = a[j];
while (i < j&&a[i] <= key) i++;
a[j] = a[i];
}
a[i] = key;
QuickSort(a, low, i - 1);
QuickSort(a, i + 1, high);
return;
}