C语言(文件练习)

发布于:2024-12-20 ⋅ 阅读:(15) ⋅ 点赞:(0)

文件的随机读写

  • 说明: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

案例

#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:

#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;
 }
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:

 #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;
 }
  1. 编写程序实现文件拷贝(用 fgets函数实现)

    #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。
2. 从键盘输入一串字符,存放到一个文件中,后打开读取存到内存另一个空间并显示,验证是否 正确键盘接收–> 存放到文件–>读文件–>显示内容

#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表示程序执行成功。

  1. 定义一个表示公交线路的结构体,要求有线路名称,起始站,终点站,里程等成员,定义结构 体数组,用来存储4条公交线路信息,并将数据保存到文件。要求验证是否存储成功。

    #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函数打印出错信息,并通过返回值指示函数执行结果。

  1. 自行查找 fscanf 和 fprintf 函数,并尝试用这两个函数进行数据的保存和读取。

    #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,表示程序执行成功。