文件的随机读写
- 说明:C语言允许程序员在读写文件内容的时候,可在指定位置上读数据
- 文件随机读写的核心操作:文件位置指针的定位
- 文件位置指针移动方法:
- rewind
- 头文件:#include<stdio.h>
- 函数原型void rewind(FILE* fp)
- 函数功能:将文件位置定位到文件开头
- 函数参数:
- fp:已经打开文件的指针
- 返回值:空类型
- fseek
- 头文件:#include<stdio.h>
- 函数原型:int fseek(FILE* fp,long offest,int whence);
- 函数功能:将文件位置指针定位到指定位置
- 函数参数:
- fp:已经打开的文件指针
- offest:相对于参考位置的偏移量
- whence:参考位置
- SEEK_SET或0:表示文件头
- SEEK_SET或1:表示当前读写的位置
- SEEK_END或2:表示文件尾
- 返回值:
- 成功:0
- 失败:-1
- ftell
- 头文件:#include<stdio.h>
- 函数原型:long ftell(FLIE* fp)
- 函数功能:获取文件位置指针当前的位置
- 函数参数:
- fp:已经打开的文件指针
- 返回值:
- 成功:文件位置指向当前的位置
- 失败:-1
- rewind
案例
c
#include <stdio.h>
int main(int argc,char *argv[])
{
// 创建两个指针,用来接收打开的文件
FILE *fp1, *fp2;
if(argc < 2)
{
perror("请使用<%s 被读取文件 被写入文件>的方式!\n");
return -1;
}
// 打开文件
fp1 = fopen(argv[1],"r");
fp2 = fopen(argv[2],"w");
// 第一次,读取文件内容通过控制台打印
while(!feof(fp1))
putchar(getc(fp1));// 输出到控制台
// 将指针指向文件的头,否则下次读取文件,会读取不到内容
rewind(fp1);
// 第二次,读取文件内容将其拷贝至fp2对应的文件中
while(!feof(fp1))
putc(getc(fp1),fp2);// 输出到文件
// 关闭文件
fclose(fp1);
fclose(fp2);
return 0;
}
案例2:
c
#include <stdio.h>
#define SIZE 10 // 学生数量
// 创建学生结构体数组
struct Student
{
char name[20];
int num;
int age;
char sex;
}stus[SIZE];
/**
* 保存学生信息到文件
*/
int save()
{
FILE* fp;
int i;
// 打开文件
if((fp = fopen("stu-dat","wb"))==NULL) // wb 二进制写入
{
perror("文件打开失败!");
return -1;
}
// 写入数据
for(i = 0; i < SIZE; i++)
{
fwrite(&stus[i],sizeof(struct Student),1,fp);
}
// 关闭文件
fclose(fp);
return 0;
}
int main(int argc,char *argv[])
{
int i;
printf("请输入学生的信息:姓名,学号,年龄,性别\n");
for(i = 0; i < SIZE;i++)
{
scanf("%s%d%d%s",stus[i].name,&stus[i].num,&stus[i].age,&stus[i].sex);
// 保存信息到文件
save();
}
return 0;
}
c
include <stdio.h>
#include <stdlib.h>
// 定义一个学生结构体
typedef struct Student
{
char name[20];
int num;
int age;
char sex;
} Stu;
// 创建一个学生数组
Stu stu[10] = {0};
int main(int argc,char *argv[])
{
int i;
FILE *fp;
// 打开文件
if((fp = fopen("stu-dat","rb"))==NULL)
{
perror("文件打开失败!\n");
return -1;
}
// 循环取出数据
for(i = 0; i < 10; i+=2)
{
// 跳过对应位置,改变文件指针的指向
fseek(fp,i*sizeof(Stu),0);
// 读数据
fread(&stu[i],sizeof(Stu),1,fp);
// 输出到控制台
printf("%s,%d,%d,%c\n",stu[i].name,stu[i].num,stu[i].age,stu[i].sex);
}
// 关闭文件
fclose(fp);
return 0;
}
案例3:
c
#include <stdio.h>
int main(int argc,char *argv[])
{
long p;
FILE *fp;
if((fp = fopen(argv[1],"a"))== NULL) // 此时的mode:a代表追加(a是append)
{
perror("文件打开失败!");
return -1;
}
// 获取当前位置
p = ftell(fp);
printf("p=%ld\n",p);
// 向文件添加数据
fputs("data",fp);
p = ftell(fp);
printf("p=%ld\n",p);
fclose(fp);
return 0;
}
-
编写程序实现文件拷贝(用 fgets函数实现)
c#include <stdio.h> #include <stdlib.h> #define BUFFER_SIZE 1024 void copyFile(const char *sourcePath, const char *destPath) { FILE *sourceFile = fopen(sourcePath, "r"); if (sourceFile == NULL) { perror("Error opening source file"); exit(EXIT_FAILURE); } FILE *destFile = fopen(destPath, "w"); if (destFile == NULL) { perror("Error opening destination file"); fclose(sourceFile); exit(EXIT_FAILURE); } char buffer[BUFFER_SIZE]; while (fgets(buffer, BUFFER_SIZE, sourceFile) != NULL) { if (fputs(buffer, destFile) == EOF) { perror("Error writing to destination file"); fclose(sourceFile); fclose(destFile); exit(EXIT_FAILURE); } } if (ferror(sourceFile)) { perror("Error reading from source file"); } fclose(sourceFile); fclose(destFile); } int main() { const char *sourcePath = "source.txt"; const char *destPath = "dest.txt"; copyFile(sourcePath, destPath); printf("File copied successfully.\n"); return 0; }
这个代码片段实现了一个将源文件复制到目标文件的函数copyFile,以及一个主函数main。
函数copyFile接受两个文件路径作为参数,打开源文件和目标文件,并使用一个大小为BUFFER_SIZE的缓冲区逐行从源文件读取内容,然后将内容写入目标文件。如果在读取或写入过程中出现错误,会打印错误信息并退出程序。
主函数main首先定义了源文件路径sourcePath和目标文件路径destPath,然后调用copyFile函数将源文件复制到目标文件。最后打印"File copied successfully."。
这段代码使用了C语言的标准输入输出库stdio.h和标准库stdlib.h,并定义了一个缓冲区大小常量BUFFER_SIZE。
- 从键盘输入一串字符,存放到一个文件中,后打开读取存到内存另一个空间并显示,验证是否 正确键盘接收--> 存放到文件-->读文件-->显示内容
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 1024 // 定义输入字符串的最大长度
int main()
{
char input[MAX_LENGTH];
char fileContent[MAX_LENGTH];
FILE *file;
// 从键盘获取输入
printf("请输入一串字符(最多%d个字符):\n", MAX_LENGTH - 1);
if (fgets(input, MAX_LENGTH, stdin) == NULL)
{
perror("读取输入失败");
return EXIT_FAILURE;
}
// 去除可能的换行符(如果输入了完整的一行)
size_t len = strlen(input);
if (len > 0 && input[len - 1] == '\n')
{
input[len - 1] = '\0';
}
// 打开文件以写入模式
file = fopen("output.txt", "w");
if (file == NULL)
{
perror("打开文件失败");
return EXIT_FAILURE;
}
// 将输入写入文件
if (fputs(input, file) == EOF)
{
perror("写入文件失败");
fclose(file);
return EXIT_FAILURE;
}
// 关闭文件
fclose(file);
// 重新打开文件以读取模式
file = fopen("output.txt", "r");
if (file == NULL)
{
perror("重新打开文件失败");
return EXIT_FAILURE;
}
// 从文件中读取内容到内存
if (fgets(fileContent, MAX_LENGTH, file) == NULL)
{
perror("读取文件失败");
fclose(file);
return EXIT_FAILURE;
}
// 关闭文件
fclose(file);
// 显示读取的内容
printf("从文件中读取的内容是:\n%s\n", fileContent);
// 验证正确性(简单比较,不考虑换行符和空格的差异)
if (strcmp(input, fileContent) == 0)
{
printf("验证成功:输入的内容与从文件中读取的内容一致。\n");
}
else
{
printf("验证失败:输入的内容与从文件中读取的内容不一致。\n");
}
return EXIT_SUCCESS;
}
该程序的功能是从键盘获取一串字符,将其写入名为"output.txt"的文件中,并重新读取文件内容进行验证。主要的代码逻辑如下:
定义了输入字符串的最大长度为1024,以及用于存储输入和文件内容的字符数组input和fileContent。
通过fgets函数从键盘获取输入字符串,并将其存储在input数组中。如果读取失败,会输出错误信息,并返回EXIT_FAILURE。
对输入字符串进行处理,去除可能的换行符。如果输入了完整的一行,最后一个字符为换行符,则将其替换为字符串结束符'\0'。
打开名为"output.txt"的文件,以写入模式。如果打开失败,会输出错误信息,并返回EXIT_FAILURE。
使用fputs函数将输入字符串写入文件中。如果写入失败,会输出错误信息,并在关闭文件后返回EXIT_FAILURE。
关闭文件。
重新打开名为"output.txt"的文件,以读取模式。如果打开失败,会输出错误信息,并返回EXIT_FAILURE。
使用fgets函数从文件中读取内容,存储在fileContent数组中。如果读取失败,会输出错误信息,并在关闭文件后返回EXIT_FAILURE。
关闭文件。
输出从文件中读取的内容。
进行输入内容和文件内容的验证,简单地比较两者是否相等。如果相等,输出验证成功的提示信息,否则输出验证失败的提示信息。
返回EXIT_SUCCESS表示程序执行成功。
-
定义一个表示公交线路的结构体,要求有线路名称,起始站,终点站,里程等成员,定义结构 体数组,用来存储4条公交线路信息,并将数据保存到文件。要求验证是否存储成功。
c#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINES 4 #define MAX_NAME_LEN 50 #define MAX_STATION_LEN 50 // 定义公交线路结构体 typedef struct { char lineName[MAX_NAME_LEN]; char startStation[MAX_STATION_LEN]; char endStation[MAX_STATION_LEN]; float distance; } BusLine; // 函数声明 void saveToFile(const char *filename, BusLine lines[], int numLines); int verifyStorage(const char *filename, BusLine lines[], int numLines); int main() { // 定义公交线路数组并初始化 BusLine lines[MAX_LINES] = { {"Line1", "StationA", "StationB", 10.5f}, {"Line2", "StationC", "StationD", 15.2f}, {"Line3", "StationE", "StationF", 20.8f}, {"Line4", "StationG", "StationH", 25.3f}}; // 打印初始化数据 printf("初始化数据:\n"); for (int i = 0; i < MAX_LINES; i++) { printf("线路 %d: %s from %s to %s, distance %.1f\n", i + 1, lines[i].lineName, lines[i].startStation, lines[i].endStation, lines[i].distance); } // 将数据保存到文件 const char *filename = "bus_lines.txt"; saveToFile(filename, lines, MAX_LINES); printf("数据已保存到文件 %s\n", filename); // 验证数据是否存储成功 if (verifyStorage(filename, lines, MAX_LINES)) { printf("数据成功存储到文件并验证通过。\n"); } else { printf("数据存储到文件失败或验证不通过。\n"); } return 0; } // 将公交线路数据保存到文件 void saveToFile(const char *filename, BusLine lines[], int numLines) { FILE *file = fopen(filename, "w"); if (file == NULL) { perror("打开文件失败"); exit(EXIT_FAILURE); } printf("正在将数据写入文件 %s...\n", filename); for (int i = 0; i < numLines; i++) { fprintf(file, "%s %s %s %.1f\n", lines[i].lineName, lines[i].startStation, lines[i].endStation, lines[i].distance); printf("写入: %s %s %s %.1f\n", lines[i].lineName, lines[i].startStation, lines[i].endStation, lines[i].distance); } fclose(file); printf("数据写入完成。\n"); } // 从文件中读取公交线路数据并验证是否与原始数据一致 int verifyStorage(const char *filename, BusLine lines[], int numLines) { FILE *file = fopen(filename, "r"); if (file == NULL) { perror("打开文件失败"); return 0; } BusLine readLines[MAX_LINES]; printf("正在从文件 %s 读取数据...\n", filename); for (int i = 0; i < numLines; i++) { if (fscanf(file, "%s %s %s %f", readLines[i].lineName, readLines[i].startStation, readLines[i].endStation, &readLines[i].distance) != 4) { fclose(file); printf("读取数据失败。\n"); return 0; } printf("读取: %s %s %s %.1f\n", readLines[i].lineName, readLines[i].startStation, readLines[i].endStation, readLines[i].distance); } fclose(file); printf("数据读取完成。\n"); // 验证读取的数据是否与原始数据一致 printf("正在验证数据...\n"); for (int i = 0; i < numLines; i++) { if (strcmp(lines[i].lineName, readLines[i].lineName) != 0 || strcmp(lines[i].startStation, readLines[i].startStation) != 0 || strcmp(lines[i].endStation, readLines[i].endStation) != 0 || lines[i].distance != readLines[i].distance) { printf("验证失败。\n"); return 0; } } printf("验证通过。\n"); return 1; }
这段代码实现了一个公交线路管理系统。它包括以下主要功能:
定义了一个公交线路结构体,包含线路名称、起始站点、终点站点和距离。
实现了一个saveToFile函数,用于将公交线路数据保存到文件中。它通过循环遍历公交线路数组,将每个线路的信息按照指定格式写入到文件中。
实现了一个verifyStorage函数,用于从文件中读取公交线路数据,并验证读取的数据是否与原始数据一致。它通过循环遍历公交线路数组,读取文件中的每一行数据并与原始数据进行比较,如果有任何不一致,则验证失败。
在主函数中,先初始化了一个公交线路数组,并打印初始化数据。然后调用saveToFile函数将数据保存到文件中,并打印保存成功的消息。最后调用verifyStorage函数验证数据是否成功存储到文件中。
这段代码主要涉及文件的读写操作,以及字符串的比较操作。通过将数据保存到文件中,并从文件中读取数据进行验证,可以确保数据的持久化和一致性。
值得注意的是,文件操作涉及到打开文件、写入数据、关闭文件等过程,需要检查每个步骤是否成功,以及适时处理错误。代码中使用了perror函数打印出错信息,并通过返回值指示函数执行结果。
-
自行查找 fscanf 和 fprintf 函数,并尝试用这两个函数进行数据的保存和读取。
c#include <stdio.h> #include <stdlib.h> int main() { // 定义文件名 const char *filename = "data.txt"; // 要写入文件的数据 int num1 = 42; float num2 = 3.14f; char str[] = "Hello, World!"; // 打开文件进行写入(如果文件不存在则创建) FILE *file = fopen(filename, "w"); if (file == NULL) { perror("Failed to open file for writing"); return EXIT_FAILURE; } // 使用 fprintf 将数据写入文件 fprintf(file, "%d %f %s\n", num1, num2, str); // 关闭文件 fclose(file); // 打开文件进行读取 file = fopen(filename, "r"); if (file == NULL) { perror("Failed to open file for reading"); return EXIT_FAILURE; } // 定义变量来存储从文件中读取的数据 int read_num1; float read_num2; char read_str[100]; // 使用 fscanf 从文件中读取数据 if (fscanf(file, "%d %f %s", &read_num1, &read_num2, read_str) != 3) { perror("Failed to read data from file"); fclose(file); return EXIT_FAILURE; } // 关闭文件 fclose(file); // 打印读取的数据 printf("Read from file: %d %f %s\n", read_num1, read_num2, read_str); return EXIT_SUCCESS; }
这段代码展示了如何使用C语言的文件操作函数来读写文件。
首先,在程序中定义了一个文件名,即"data.txt"。然后定义了要写入文件的数据,包括一个整数num1,一个浮点数num2,和一个字符串str。
接下来,使用fopen函数打开文件进行写入操作,并将返回的文件指针赋值给变量file。如果文件打开失败,会输出错误信息并返回EXIT_FAILURE。
然后使用fprintf函数将数据写入文件,按照指定的格式将num1、num2和str写入文件。
写入完成后,使用fclose函数关闭文件。
然后再次使用fopen函数打开文件进行读取操作,并将返回的文件指针赋值给变量file。如果文件打开失败,同样会输出错误信息并返回EXIT_FAILURE。
接下来定义了变量read_num1、read_num2和read_str,用于存储从文件中读取的数据。
使用fscanf函数从文件中读取数据,并按照指定的格式将读取到的数据存储到相应的变量中。如果读取失败,会输出错误信息并关闭文件,然后返回EXIT_FAILURE。
最后使用fclose函数关闭文件,并使用printf函数打印读取到的数据。
整个程序最后返回EXIT_SUCCESS,表示程序执行成功。