C语言进阶输入输出重定向与fopen函数使用示例详解

 更新时间:2022年02月15日 11:13:50   作者: hxj7  
这篇文章主要为大家介绍了C语言进阶输入输出重定向与fopen函数的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步

正片开始

大多数情况下,我们所熟知的输入输出都是标准I/O(标准输入输出),也就是我们在写代码时会直接从键盘读取,从屏幕输出。但是当我们涉及到数据统计或者多组未定义内容输入时,我们的程序就会出现一些小问题

int n = 0;
while(scanf("%d",&n)==1)

按照常理来说,这里 scanf 的返回值是成功输入的数的个数,输入一但结束,scanf 函数就无法继续读取 n,返回0,我们测试一下,输入“1,2,3,4,5”看看,好家伙,根本没有结果显示。是代码问题还是运行太慢?其实是还在等待输入,虽然我们可能觉得一个回车就可以搞定,但程序不会。

记得 scanf 的输入格式上对于空格,Tab,Enter键都是一视同仁,那如何才能告诉 程序我们输入结束了呢?在Windows下,输入完毕后先按Enter键,再按Ctrl+Z键,最后再按Enter才能结束输入。在Linux下,只需Ctrl+Z即可结束输入。

也就是说上面的程序不是很方便,每次测试需要手动输入很多数,如果面对多组输入并且需要大量验证的测试,数据也只能保存在命令行中,仍然不够方便。

输入输出重定向

以上场景我们有个好的方法就是用文件把输入输出的数据放在文件里面,也就是所谓的输入输出重定向,放入事先准备好的数据,就不必每次重复输入了,也可以太多的输出一卷屏跑出来,属实不方便,而且在文件中放好标准的答案,可以很方便的进行比对,无需我们再去逐一的排查。有个不争的事实就是几乎所有算法的输出数据和标准答案都是放在文件里的。

在使用输入输出重定向时,只需在main函数的入口处加入两条语句:

freopen("input.txt","r","stdin");
freopen("output.txt","w","stdout");

其作用很简单,就是使得scanf从文件 input.txt 读入,printf 再从output.txt输出。
我们给出一个代码:

#define Max
#include<stdio.h>
int main()
{
#ifdefine Max
freopen("input.txt","r","stdin");
freopen("output.txt","w","stdout");
#endif
}

#ifdefine Max#endif 的特殊之处就是我们只有在Max被定义了情况下才可以编译这两条 freopen 语句。事实上不只scanf 和 printf,所用从键盘键入从屏幕输出的数据都会改用文件,这确实方便,但在很多算法竞赛中禁止访问文件,甚至允许访问文件却禁止使用 freopen 这样的重定向读写文件。这种特殊情况我们又该作何打算呢?没错,那就是 fopen 函数

fopen函数

fopen函数表达式为:

FILE *fopen(char *filename, *type);

这个表达式不细说,只作了解,又是一堆晦涩陌生的名词,有兴趣的可以自行搜索。
我们来看个代码:

FILE *fin,*fout;
fin = fopen("test.in","r");
fout = fopen("test.out","w");
fclose(fin);
fclose(fout);

这里先声明了变量fin 和 fout,后续如果要输入输出我们需要把printf改为fprintf ,把 scanf 改为 fscanf,最后fclose关闭两个文件。

fopen和 freopen长的差不多,起初我甚至觉得他们就是一个东西,freopen和fopen之间有各自的优劣,重定向的方法写起来简单自然,但不能同时读写文件与标准输入输出;fopen写法稍微繁琐一点,但灵活性更大,就可以反复打开和读写文件。

这里的fscanf,fprintf都是针对数据流的,而什么是数据流?

数据流是一组有序,有起点和终点的字节的数据序列,包括输入流和输出流。就像水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流。数据写入程序可以是一段、一段地向数据流管道中写入数据,这些数据段会按先后顺序形成一个长的数据流。对数据读取程序来说,看不到数据流在写入时的分段情况,每次可以读取其中的任意长度的数据,但只能先读取前面的数据后,再读取后面的数据。不管写入时是将数据分多次写入,还是作为一个整体一次写入,读取时的效果都是完全一样的。

“流是磁盘或其它外围设备中存储的数据的源点或终点。”

而对于fscanf 的使用难点在于以下几点:

  • 对空白符的处理(空格、制表符、换行符);
  • *的用法;
  • [] 以及 [^] 的用法;
  • EOF 的处理;

上述问题,网上的文章都语焉不详,具体内容参见 fscanf详谈

当我们想把fopen的程序改成标准输入输出,只需赋值"fin = stdin;fout = stdout",不用再调用fopen和fclose。

今天就先到这里吧,摸了家人们,更多关于C语言输入输出重定向fopen函数的资料请关注脚本之家其它相关文章!

相关文章

  • C++ 删除字符串的2种方法小结

    C++ 删除字符串的2种方法小结

    这篇文章主要介绍了C++ 删除字符串的2种方法小结,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • OpenCV图像几何变换之透视变换

    OpenCV图像几何变换之透视变换

    这篇文章主要为大家详细介绍了OpenCV图像几何变换之透视变换,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • 使用C语言实现五子棋游戏

    使用C语言实现五子棋游戏

    这篇文章主要为大家详细介绍了使用C语言实现五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C++示例分析内联函数与引用变量及函数重载的使用

    C++示例分析内联函数与引用变量及函数重载的使用

    为了消除函数调用的时空开销,C++ 提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开。这种在函数调用处直接嵌入函数体的函数称为内联函数(Inline Function),又称内嵌函数或者内置函数
    2022-08-08
  • 深入探索C++ string的底层实现

    深入探索C++ string的底层实现

    C语言中的字符串是以字符数组的形式存储的,每个字符占用一个字节的内存空间,本文我们将和大家一起深入探讨一下string的底层实现,感兴趣的小伙伴快来和小编一起吧
    2023-08-08
  • C++数组放在main函数内外的区别

    C++数组放在main函数内外的区别

    大家好,本篇文章主要讲的是C++数组放在main函数内外的区别,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • C++基于Boost.Asio实现端口映射器的过程详解

    C++基于Boost.Asio实现端口映射器的过程详解

    Boost.Asio 是一个功能强大的 C++ 库,用于异步编程和网络编程,它提供了跨平台的异步 I/O 操作,在这篇文章中,我们将深入分析一个使用 Boost.Asio 实现的简单端口映射服务器,文中有详细的代码讲解,需要的朋友可以参考下
    2023-11-11
  • c++ 如何合并两个有序链表

    c++ 如何合并两个有序链表

    这篇文章主要介绍了c++ 如何合并两个有序链表,帮助大家更好的理解和学习C++,感兴趣的朋友可以了解下
    2020-08-08
  • C语言实现一个多线程委托模型的示例详解

    C语言实现一个多线程委托模型的示例详解

    这篇文章主要介绍了C语言实现一个多线程委托模型,这就是一个使用C语言实现多线程委托模型的例子,其中包含boss线程和worker线程,可以处理工作线程的异常情况,需要的朋友可以参考下
    2023-06-06
  • 基于C语言实现个人通讯录管理系统

    基于C语言实现个人通讯录管理系统

    这篇文章主要为大家详细介绍了基于C语言实现个人通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06

最新评论