【C语言基础】:文件操作详解(后篇)-1

简介: 【C语言基础】:文件操作详解(后篇)

上期回顾: 【C语言基础】:文件操作详解(前篇:准备知识)

一、文件的顺序读写

1.1 顺序函数读写函数介绍

34a42b323e5533c29e632b3ac2580773_079250551903431b9f7c87ad2526d59c.png


1.2 fgetc函数和fputc函数

fputc函数原型:

int fputc ( int character, FILE * stream );

将字符写入流

将一个字符写入流并推进位置指示器。

字符被写入流的内部位置指示器所指示的位置,然后自动向前移动一个。


参数说明:


character: 要写入的字符,以整数形式表示。

stream :指向要写入的文件的文件指针。


函数返回值:


如果成功写入字符,则返回写入的字符,如果发生错误,则返回 EOF。


【示例1】:


#include<stdio.h>
int main()
{
  // 打开文件
  FILE* pf = fopen("test1.txt", "w");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 写文件
  fputc('a', pf);
  fputc('b', pf);
  fputc('c', pf);
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}


【示例2】:

#include<stdio.h>
int main()
{
  // 打开文件
  FILE* pf = fopen("test1.txt", "w");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 写文件
  char ch = 0;
  for (ch = 'A'; ch <= 'Z'; ch++)
  {
    fputc(ch, pf);
  }
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

0cb28d4f5ed1acf85081eeeec80d093a_dde6ab60a21c4bb992d4df7a1617bc58.png

503a553aa0ebecc31f007927979773c9_2db2edb95db342c79ef35b066a6fbc31.png


fgetc函数原型:

int fgetc ( FILE * stream );

从流中获取字符

返回指定流的内部文件位置指示符当前指向的字符。然后将内部文件位置指示符推进到下一个字符。

如果流在被调用时位于文件的末尾,则该函数返回EOF并为流设置文件结束指示器(feof)。

如果发生读错误,该函数返回EOF并设置流的错误指示器(error)。

fgetc和fgetc是等价的,除了getc可以在某些库中作为宏实现。


参数说明:


stream: 指向要读取的文件的文件指针。


函数返回值:


如果成功读取一个字符,则返回读取的字符,如果已到达文件末尾或发生错误,则返回 EOF。

返回值是整形的原因:


  1. 读取成功,返回该字符的ASCII值。
  2. 读到文件末尾或则读取失败,返回EOF(-1)。

【示例1】:

#include<stdio.h>
int main()
{
  // 打开文件
  FILE* pf = fopen("test1.txt", "r");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 读文件
  int ch = fgetc(pf);
  printf("%c", ch);

  ch = fgetc(pf);
  printf("%c", ch);

  ch = fgetc(pf);
  printf("%c", ch);
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

29a2f4975298bd10135dd0770f555e54_53a56e2057a8411190e355c7d0fec088.png

【示例2】:


#include<stdio.h>
int main()
{
  // 打开文件
  FILE* pf = fopen("test1.txt", "r");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 读文件
  char ch = 0;
  while ((ch = fgetc(pf)) != EOF)
  {
    printf("%c", ch);
  }
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

d74b8b51eb52486d89ddbc0416cd7198_06b07ec74edb426c881a9ac9f51b1d89.png


1.3 fputs函数和fgets函数

fputs函数原型:

int fputs ( const char * str, FILE * stream );

将字符串写入流

将由str指向的C字符串写入流。

函数从指定的地址(str)开始复制,直到到达结束的空字符(‘\0’)。这个终止的空字符不会复制到流中。

注意,fputs与puts的不同之处不仅在于可以指定目标流,而且fputs不会写入额外的字符,而puts会自动在末尾附加一个换行符。


参数说明:


str: 要写入的字符串,以 const char * 类型表示。

stream: 指向要写入的文件的文件指针。


函数返回值:


如果成功写入字符串,则返回非负值(通常为 0),如果发生错误,则返回 EOF。


【示例】:


#include<stdio.h>
int main()
{
  // 打开文件
  FILE* pf = fopen("test1.txt", "w");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 写文件
  fputs("hello", pf);
  fputs(" world", pf);
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

fgets函数原型:

char * fgets ( char * str, int num, FILE * stream );

从流中获取字符串

从流中读取字符,并将其作为C字符串存储到str中,直到读取(num-1)个字符,或者到达换行符或文件结束符,以先发生的为准。

换行符使fgets停止读取,但它被函数认为是一个有效字符,并包含在复制到str的字符串中。

在复制到str的字符之后,将自动追加一个终止null字符。

请注意,fgets与gets有很大的不同:fgets不仅接受流参数,而且允许指定str的最大长度,并在字符串中包含任何结束换行符。

参数说明:


str: 一个指向字符数组的指针,用于存储读取的字符。

num: 要读取的最大字符数(包括空字符),通常是 str 缓冲区的大小。

stream: 指向要读取的文件的文件指针。


函数返回值:


如果成功读取一行字符,则返回 str 参数的值;如果到达文件末尾或发生错误,则返回 NULL。


【示例】:

#include<stdio.h>
int main()
{
  // 打开文件
  FILE* pf = fopen("test1.txt", "r");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 读文件
  char arr[10] = { 0 };
  fgets(arr, 10, pf);
  printf("%s\n", arr);
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

注意:要求读10个字符,结果却只读9个,因为\0也会算进去。

1.4 fprintf函数和fscanf函数

fprintf函数原型:

int fprintf ( FILE * stream, const char * format, ... );

将格式化的数据写入流

将由format指向的C字符串写入流。如果format包含格式说明符(以%开头的子序列),则格式化format之后的其他参数并将其插入到结果字符串中,以替换它们各自的说明符。

在format形参之后,函数期望至少与format指定的一样多的附加参数。


参数说明如下:


stream:指向文件的指针,它指定了数据将要被写入的文件。

format:一个格式化字符串,其中包含了要写入的数据以及格式化说明符。

…:可变数量的参数,根据 format 字符串中的格式化说明符指定了要写入的数据。

fprintf 函数的返回值是一个 int 类型,表示成功写入的字符数,如果发生错误则返回一个负数。


【示例】:

#include<stdio.h>
struct S
{
  char name[20];
  int age;
  float score;
};
int main()
{
  struct S s = { "张三", 19, 89.5 };
  // 打开文件
  FILE* pf = fopen("test1.txt", "w");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 写文件
  fprintf(pf, "%s %d %f", s.name, s.age, s.score);
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

fscanf函数原型:

int fscanf ( FILE * stream, const char * format, ... );

从流中读取格式化的数据

从流中读取数据,并根据参数格式将其存储到附加参数所指向的位置。

额外的参数应该指向已经分配的对象,其类型由格式字符串中相应的格式说明符指定。


参数说明如下:


stream:指向文件的指针,它指定了从中读取数据的文件。

format:一个格式化字符串,其中包含了要读取的数据的格式化说明符。

…:可变数量的参数,根据 format 字符串中的格式化说明符指定了要读取的数据。

fscanf 函数的返回值是一个 int 类型,表示成功读取并匹配的数据项的数量。如果到达文件结束或发生读取错误,则返回 EOF (-1)。


【示例】:


#include<stdio.h>
struct S
{
  char name[20];
  int age;
  float score;
};
int main()
{
  struct S s = { "张三", 19, 89.5f };
  // 打开文件
  FILE* pf = fopen("test1.txt", "r");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 读文件
  fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));
  // 打印到屏幕上
  printf("%s %d %f\n", s.name, s.age, s.score);
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

e126a9e899212b7730fbb84389f2cdb5_32c9540dcb50475090531ec72550b309.png


1.5 fwrite函数和fread函数

fwrite函数原型:

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

将数据块写入流

将由count元素组成的数组(每个元素的大小为size字节)从ptr所指向的内存块写入流中的当前位置。

流的位置指示器按写入的总字节数前进。

在内部,该函数将ptr指向的块解释为unsigned char类型的(size*count)元素数组,并将它们顺序写入流,就像对每个字节调用fputc一样。


参数说明如下:


ptr:指向要写入的数据块的指针。

size:每个数据项的大小(以字节为单位)。

count:要写入的数据项的数量。

stream:指向文件的指针,它指定了数据将要被写入的文件。

fwrite 函数的返回值是一个 size_t 类型,表示成功写入的数据项的数量。如果发生错误,则返回一个小于 count 的值。


【示例】:


#include<stdio.h>
int main()
{
  int arr[] = { 1,2,3,4,5 };
  // 打开文件
  FILE* pf = fopen("test1.txt", "wb");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 写文件
  int sz = sizeof(arr) / sizeof(arr[0]);
  fwrite(arr, sizeof(arr[0]), sz, pf);  // 以二进制的形式写入 
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

8d520bca63246cb49a9c033c6408b656_4ad7b75db5f14bb0ab3545f53cee869f.png

5b240cfbe67a3be91cd5abebf07feb26_61841fa5c88e4c8286e3e14bebdf05fd.png

fread函数原型:

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

从流中读取一个由count元素组成的数组,每个元素的大小为size字节,并将它们存储在ptr指定的内存块中。

流的位置指示器按读取的总字节数前进。

如果成功读取的总字节数为(size*count)。


参数说明如下:


ptr:指向存储读取数据的缓冲区的指针。

size:每个数据项的大小(以字节为单位)。

count:要读取的数据项的数量。

stream:指向文件的指针,它指定了从中读取数据的文件。

fread 函数的返回值是一个 size_t 类型,表示成功读取的数据项的数量。如果到达文件末尾或发生读取错误,则返回一个小于 count 的值。


【示例】:


#include<stdio.h>
int main()
{
  int arr[5] = { 0 };
  // 打开文件
  FILE* pf = fopen("test1.txt", "rb");
  if (pf == NULL)
  {
    perror("fopen");
    return 1;
  }
  // 读文件
  fread(arr, sizeof(arr[0]), 5, pf);
  for (int i = 0; i < 5; i++)
  {
    printf("%d ", arr[i]);
  }
  // 关闭文件
  fclose(pf);
  pf = NULL;
  return 0;
}

98f338b9322ace4a08331bff29611db2_60b9c5a20af24f03865728abd8ff9bd1.png

上面说的适用于所有输入流一般指适用于标准输入流和其他输入流(如文件输入流);所有输出流一般指适用于标准输出流和其他输出流(如文件输出流)


【C语言基础】:文件操作详解(后篇)-2

https://developer.aliyun.com/article/1538345

相关文章
|
20天前
|
存储 C语言
【c语言】玩转文件操作
本文介绍了C语言中文件操作的基础知识,包括文件的打开和关闭、文件的顺序读写、文件的随机读写以及文件读取结束的判定。详细讲解了`fopen`、`fclose`、`fseek`、`ftell`、`rewind`等函数的使用方法,并通过示例代码展示了如何进行文件的读写操作。最后,还介绍了如何判断文件读取结束的原因,帮助读者更好地理解和应用文件操作技术。
27 2
|
1月前
|
存储 C语言
C语言文件操作(2)
【10月更文挑战第2天】
|
1月前
|
程序员 编译器 C语言
C语言底层知识------文件操作
本文详细介绍了文件操作的基本概念,包括文件的分类(程序文件和数据文件,其中着重于数据文件的文本文件和二进制文件),流的概念及其在C程序中的应用,以及标准输入输出流stdin、stdout和stderr的作用。作者通过示例展示了如何使用fopen、fclose和常见的读写函数如fgetc、fputc和fgets进行文件操作。
21 2
|
2月前
|
C语言
C语言——文件操作
本文介绍了文件的基本操作,包括文件的打开、关闭、读取和写入。使用`fopen`函数以不同模式(如“r”、“w”等)打开文件,并通过`fclose`关闭。文章详细解释了如何利用`fputc`、`fputs`及`fprintf`进行格式化写入,同时介绍了`fgetc`、`fgets`和`fscanf`用于文件内容的读取。此外,还涵盖了二进制文件的读写方法以及如何通过`fseek`、`ftell`和`rewind`实现文件的随机访问。
50 1
C语言——文件操作
|
1月前
|
存储 缓存 编译器
文件操作——C语言
文件操作——C语言
|
1月前
|
存储 C语言
简述C语言文件操作
简述C语言文件操作
11 0
|
1月前
|
存储 文件存储 C语言
深入C语言:文件操作实现局外影响程序
深入C语言:文件操作实现局外影响程序
|
1月前
|
存储 程序员 编译器
C语言文件操作(1)
【10月更文挑战第1天】
|
1月前
|
存储 C语言
C语言的文件操作
C语言的文件操作
21 0
|
1月前
|
存储 移动开发 Unix
C 语言文件操作详解
C 语言文件操作详解