【文件操作的重难点详解】(二)

简介: 【文件操作的重难点详解】(二)

1.3格式化输出函数(fprintf)&&格式化输入函数(fscanf)

格式化输出函数(向文件中写入信息):

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

7509de4e5cd0417f9e8589e759180902.png
struct stu
{
  char name[10];
  char sex[5];
  int age;
  double weight;
};
int main()
{
  struct stu s = { "lisi","男",18,60.0 };
  FILE* pf = fopen("text.txt", "w");
  if (pf == NULL)
  {
    printf("%s\n", strerror(errno));
    return 0;
  }
  fprintf(pf, "%s %s %d %lf", s.name, s.sex, s.age, s.weight);//向文件中输出信息
  fclose(pf);
  pf = NULL;
  return 0;
}

  从代码中可以看到:我们将s进行了初始化,想将该内容拷贝到text.txt文件夹中:



7509de4e5cd0417f9e8589e759180902.png


代码执行后可以明显发现文件夹中已经成功拷贝。

格式化输入函数(从文件中读取信息):

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

struct stu
{
  char name[10];
  char sex[5];
  int age;
  double weight;
};
int main()
{
  struct stu s = { 0 };
  FILE* pf = fopen("text.txt", "r");
  if (pf == NULL)
  {
    printf("%s\n", strerror(errno));
    return 0;
  }
  fscanf(pf, "%s %s %d %lf", s.name, s.sex, &(s.age), &(s.weight));//从文件中获得信息
  printf("%s %s %d %lf", s.name, s.sex, s.age, s.weight);
  fclose(pf);
  pf = NULL;
  return 0;
}

代码中我们对s的内容初始化为0,代码执行后将文件夹中的内容拷贝到了s中:


13bbee6ab7fc4786b72356cf6ed3cb9d.png

我们还可以用stdin&&stdout来从键盘输入数据以及从屏幕上打印数据:


b306e170c80d4253abf1ec5593ca0859.png

1.4  扩展:

intsprintf(char*buffer,constchar*format [,argument] ... );

intsscanf(constchar*buffer,constchar*format [,argument ] ... );

int main()
{
  struct stu s1 = { "lisi","男",18,60 };
  struct stu s2 = { 0 };
  char buf[100] = { 0 };
  //把格式化的数据转换成字符串存储到buf
  sprintf(buf, "%s %s %d %lf", s1.name, s1.sex, s1.age, s1.weight);
  printf("%s\n", buf);
  //从buf中读取格式化的数据到s2中
  sscanf(buf, "%s %s %d %lf", s2.name, s2.sex, &(s2.age), &(s2.weight));
  printf("%s %s %d %lf", s2.name, s2.sex, s2.age, s2.weight);
  return 0;
}

总结:

  1. scanf/printf:是针对标准输入流/标准输出流的格式化输入/输出语句。
  2. fscanf/fprintf:是针对所有输入流/所有输出流的格式化输入/输出语句 。
  3. sscanf/sprintf:sscanf是从字符串中读取格式化数据,sprintf是把格式化数据输出成(存储到)字符串

1.5 二进制输出函数(fwrite)&&二进制输入函数(fread)

二进制输出函数

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

typedef struct stu
{
  char name[20];
  int age;
  double weight;
}stu;
int main()
{
  FILE* pf = fopen("text.txt", "wb");
  if (pf ==NULL)
  {
    printf("%s\n", strerror(errno));
  }
  stu s[2] = { {"zhangsan",18,60},{"lisi",19,65} };
  fwrite(s, sizeof(stu), 2, pf);
  fclose(pf);
  pf = NULL;
  return 0;
}

当我们查看文件里面的内容时:


f2c2a8e5805c46f0bd15884294bb1584.png

有的符号我们认识,但有的符号却很奇怪,为什么呢?

由于我们写入的时二进制的形式,所以有些符号不认识很正常,但是当我们以二进制的形式读取时就不会出现这种奇怪的符号了。

二进制输入函数:

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

typedef struct stu
{
  char name[20];
  int age;
  double weight;
}stu;
int main()
{
  FILE* pf = fopen("text.txt", "rb");
  if (pf == NULL)
  {
    printf("%s\n", strerror(errno));
  return 0;
  }
  stu s[2] = { 0 };
  fread(s, sizeof(stu), 2, pf);
  printf("%s %d %lf\n%s %d %lf", s[0].name, s[0].age, s[0].weight, s[1].name, s[1].age, s[1].weight);
  fclose(pf);
  pf = NULL;
  return 0;
}

当读取信息时就会读取正常的信息:

4f8f596a753e488d8701bd96c75f15ce.png


2 文件的随机读写

2.1 fseek:根据文件指针的位置和偏移量来定位文件指针

intfseek(FILE*stream,longoffset,intorigin );

 刚开始的时候文件中存放的是abcdef:


2c241619dceb4f598421f205627c201a.png

int main()
{
  FILE* pf = fopen("text.txt", "r");
  if (pf == NULL)
  {
    printf("%s\n", strerror(errno));
    return 0;
  }
  fseek(pf, 2, SEEK_CUR);
  int ch = fgetc(pf);
  printf("%c\n", ch);
  fclose(pf);
  pf = NULL;
  return 0;
}

e61787ad9e104a39a8a8af9652770f8a.png


在这之前我们还得了解一下origin:

SEEK_CUR

Current position of file pointer

SEEK_END

End of file

SEEK_SET

Beginning of file

至于为什么打印的是c:从a开始偏移2个字符得到的就是c.此时pf指向下一个字符(也就是d):

120999e40a064c62af0feb0663b8be8a.png

2.2 ftell :返回文件指针相对于起始位置的偏移量

long ftell( FILE *stream );



5229702bab3f4183bd3d303cc24744fd.png

这个函数的用法很简单,就不多说了。

2.3 rewind :让文件指针的位置回到文件的起始位置

void rewind( FILE *stream );

这个函数的作用是让pf指向文件字符的开头:


2d5669cd4c53416b9074a5c498bdd3ac.png



好了,今天的分享就到这里了。希望老铁们能够指出文章中的错误所在,酸Q。


8be4b6d0c842470ca3d35c73cf9455a4.png



目录
相关文章
|
算法 数据挖掘 Go
文献速读|5分生信+免疫组化单细胞联合bulk转录组肿瘤预后模型
研究摘要: 在《Cancer Immunology Immunotherapy》上发表的一篇文章,通过整合Bulk和单细胞RNA-seq数据,探讨了非小细胞肺癌(NSCLC)中癌相关纤维细胞(CAF)的作用。研究者识别出CAF的预后标志物,构建了一个基于CAF的模型,该模型在四个独立队列中区分了预后良好的和较差的患者。WGCNA分析鉴定出CAF标记基因,而CAF分数与免疫微环境和免疫治疗反应相关。高CAF分数关联较差的免疫治疗反应,FBLIM1被发现为CAF的主要来源,其高表达预测了免疫疗法的不良反应。该研究揭示了CAF在NSCLC免疫抑制和治疗策略中的重要地位。
478 1
全网首发:gstreamer如何接入RTSP流(IP摄像头)的代码范例
全网首发:gstreamer如何接入RTSP流(IP摄像头)的代码范例
959 0
|
存储 NoSQL Linux
Linux下安装MongoDB
Linux下安装MongoDB
313 0
|
机器学习/深度学习 人工智能 自然语言处理
人工智能(AI)技术的发展史
人工智能 (AI) 的发展历程从20世纪50年代起步,历经初始探索、早期发展、专家系统兴起、机器学习崛起直至深度学习革命。1950年图灵测试提出,1956年达特茅斯会议标志着AI研究开端。60-70年代AI虽取得初步成果但仍遭遇困境。80年代专家系统如MYCIN展现AI应用潜力。90年代机器学习突飞猛进,1997年深蓝战胜国际象棋冠军。21世纪以来,深度学习技术革新了AI,在图像、语音识别等领域取得重大成就。尽管AI已广泛应用,但仍面临数据隐私、伦理等挑战。未来AI将加强人机协作、增强学习与情感智能,并在医疗、教育等领域发挥更大作用。
|
监控 Java 测试技术
实战派必看!Python性能测试中,JMeter与Locust如何助力性能调优
【8月更文挑战第6天】性能优化是软件开发的关键。本文介绍JMeter与Locust两款流行性能测试工具,演示如何用于Python应用的性能调优。JMeter可模拟大量用户并发访问,支持多种协议;Locust用Python编写,易于定制用户行为并模拟高并发。根据场景选择合适工具,确保应用在高负载下的稳定运行。
314 4
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的高校教务管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的高校教务管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
242 2
|
机器学习/深度学习 分布式计算 大数据
【大数据技术】Spark MLlib机器学习特征抽取 TF-IDF统计词频实战(附源码和数据集)
【大数据技术】Spark MLlib机器学习特征抽取 TF-IDF统计词频实战(附源码和数据集)
210 1
|
设计模式 JSON Dart
Dart笔记:build_runner-用于 Dart 代码生成和模块化编译的构建系统
Dart笔记:build_runner-用于 Dart 代码生成和模块化编译的构建系统
1000 0
|
SQL JSON 关系型数据库
「PostgreSQL」PostgreSQL 和SQL SERVER(性能和可伸缩性)
「PostgreSQL」PostgreSQL 和SQL SERVER(性能和可伸缩性)
|
JavaScript 容器
generator 和 yield的使用
generator 和 yield的使用
119 0