博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C/C++系列之数据的输入输出——基础技能一
阅读量:3933 次
发布时间:2019-05-23

本文共 8108 字,大约阅读时间需要 27 分钟。

数据输入输出

  • 在上一篇,已经对原文件的每一行进行了详细的剖析,这一篇将聚焦编程基础技能的第一项技能,也是新手阶段必须掌握的编程技能,无论学习什么高级编程语言。

一、电脑的 I/O 设备

  • 这一步,虽然与具体编程语言无关,但是却是新手必须了解的。
  • 从计算机组成角度来说,计算机的核心部分只有 CPU 和内存,其他都是辅助设备,用于进行人机交互的,其中有一大类设备统称为 I/O 设备,具体就是我们经常直接看到的鼠标、键盘、显示器和打印机等,还有一种,我们大部分没有直接看到的、在计算机机箱里的硬盘,也是属于 I/O 设备,一些新手以为计算机机箱外面的才是 I/O 设备。
  • 从计算机组成角度, I/O 设备,即外部设备,指的是 CPU 不能直接进行交互的设备,要与这些设备交互就必须将数据缓存到内存中才行。
  • 这里必须强调一点,你作为 IT 人员,你必须比其他行业的人,明确的知道日常所说的存储空间与内存或运存的区别。绝大多数人,日常所说的存储空间是指外存空间,而内存或运存是指内存条的容量。

二、程序数据来源

  • 程序就是算法加数据,如果算法是指我们的处理逻辑代码,可以提前写成脚本,那么数据又是以什么形式输入到程序,程序又以什么形式进行输出呢?

1、数据输入

  • 程序获取数据的方式有以下几种方式:
    • 1)对于少量数据,而且程序没有动态性要求,可以将数据以编程语言提供的数据类型和数据结构,提前编辑到源代码中。
    • 2)程序有动态性要求,那么数据显然不能写在源代码中,不然每次数据改变了,就要修改一次源代码,显然不合适,那么这时就需要用到计算机系统的输入设备:键盘、鼠标、屏幕或硬盘等,其中键盘、屏幕和硬盘是控制台应用程序常用的数据输入设备;具体区别就是,但数据少量时可以通过键盘进行手动输入,但是大量数据时,采用手动方式是不行的,高速的 CPU 等待慢速的手动输入,时间代价太大;所以当数据量大时,我们通常是在磁盘中建立一定文件格式的文件存放数据,如TXT、CSV 或 Excel 文件等。虽然,从磁盘读取数据的速度要比从内存读取慢很多,但是比手动输入却快很多。此外,还可以直接从 Internet 中获取数据。

2、程序处理结果输出

  • 我们输入到程序中的数据,经过逻辑处理后的结果,其输出方式主要有如下:
    • 1)如果结果数据是小规模的,可以直接输出到屏幕中。
    • 2)当结果数据规模大,则一般采取输出到一个文件的方式。

三、C/C++ 中的数据输入输出

1、简介

  • 在 C/C++ 中,标准库提供了相关函数进行数据的输入,根据库文件的归属分为C 输入函数C++ 输入函数。在 CPP 代码中,这两类函数都可以使用,只要导入所在函数库即可;但是在 C 代码中,只能使用 C 输入函数
  • 对于输出函数分类也是类似,我这里便不赘述。
  • 以下按照 C 与 C++ 的区别分别介绍输入、输出,然后代码示例。

2、C 语言的输入与输出

2.1、C 输入函数介绍

  • C 输入函数主要有用于从键盘读取数据的 scanf、getchar 和 gets,以及用于读取文件的 fgetc、fgets、fscanf 函数;读取文件,还可以使用系统函数:read 函数。
  • int scanf(const char *format, …) 函数从标准输入流 stdin 读取输入,并根据提供的 format 来浏览输入。
  • char *gets(char *s) 函数从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。
  • int getchar(void) 函数从屏幕读取下一个可用的字符,并把它返回为一个整数。这个函数在同一个时间内只会读取一个单一的字符。您可以在循环内使用这个方法,以便从屏幕上读取多个字符。
  • int fgetc( FILE * fp ) 函数从 fp 所指向的输入文件中读取一个字符。返回值是读取的字符,如果发生错误则返回 EOF。
  • char *fgets( char *buf, int n, FILE *fp ) 函数从 fp 所指向的输入流中读取 n - 1 个字符。它会把读取的字符串复制到缓冲区 buf,并在最后追加一个 null 字符来终止字符串。如果这个函数在读取最后一个字符之前就遇到一个换行符 ‘\n’ 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符。
  • int fscanf(FILE *fp, const char *format, …) 函数来从文件中读取字符串,但是在遇到第一个空格和换行符时,它会停止读取。
  • int read(int handle,void *buf,int len) 函数用于读取打开文件的内容。

2.2、C 输出函数

  • C 函数库提供了用于输出到屏幕的输出函数 printf、puchar 和 puts,以及用于将数据写入文件的 fprintf、fputc 和 fputs,以及有系统提供的用于写文件的 write 函数。
  • int printf(const char *format, …) 函数把输出写入到标准输出流 stdout ,并根据提供的格式产生输出。
  • int putchar(int c) 函数把字符输出到屏幕上,并返回相同的字符。这个函数在同一个时间内只会输出一个单一的字符。您可以在循环内使用这个方法,以便在屏幕上输出多个字符。
  • int puts(const char *s) 函数把字符串 s 和一个尾随的换行符写入到 stdout。
  • int fprintf(FILE *fp,const char *format, …) 函数来写把一个字符串写入到文件中。
  • int fputc( int c, FILE *fp ) 函数把参数 c 的字符值写入到 fp 所指向的输出流中。如果写入成功,它会返回写入的字符,如果发生错误,则会返回 EOF。
  • int fputs( const char *s, FILE *fp ) 把字符串 s 写入到 fp 所指向的输出流中。如果写入成功,它会返回一个非负值,如果发生错误,则会返回 EOF。
  • int write(int handle,char *buf,unsigned len) 功能:将缓冲区的数据写入与handle相联的文件中。
  • 细心的应该发现这些输入输出函数是配对的,接下来代码示例。

2.3、C 输入输出示例

  • 首先尝试从键盘获取数据并输出到屏幕上:
    #include 
    #include
    #include "hello.h"int main(){
    // 示例1:使用 scanf 函数和 printf ,请导入 stdio.h 文件 int num; // 声明一个整型变量 int t = scanf("%d", &num); // 第一个参数是格式控制符,后面展开,这里只需知道 %d 表示整数,& 用于取地址 printf("%d", num); // 示例二:getchar 和 putchar int num1; num1 = getchar(); putchar(num1); // 示例三:使用 gets 和 puts char str[20]; // 字符数组,后面详细展开 gets_s(str); puts(str);}
  • 接下来,先简单试一试用C语言提供的文件操作函数,对一个已经存在的文件进行读写。
  • 首先,在源文件夹里面新建一个文本文件,并取名为test。
  • 手动在main函数里敲入以下代码进行运行:
    FILE* f = NULL;f = fopen("test.txt", "r");// 分别用fscanf、fgets 和 fgetc 读取文件内容char buff[1024];fscanf(f, "%s", buff);printf("%s\n", buff);fclose(f);f = fopen("test.txt", "a");fprintf(f, ",一些追加内容");fclose(f);f = fopen("test.txt", "r");fgets(buff, 50, f);printf("%s\n", buff);fclose(f);f = fopen("test.txt", "a");fputs(",Trying写入用fputs", f);fclose(f);f = fopen("test.txt", "r");fscanf(f, "%s", buff);printf("%s\n", buff);fclose(f);
  • 控制台窗口输出如下:
    在这里插入图片描述
  • 打开test文件查看,里面内容修改为:
    在这里插入图片描述
  • 以上就是用C语言提供的库函数进行简单操作。
  • 上面的输入输出是一个基础,接下来是C语言输入输出的重头戏,格式化输入输出

2.4、C 语言格式化输入与输出

  • C 语言库函数中提供了一对格式化I/O函数,就是scanf 与 printf

  • 首先,请记住以下格式控制符:

    在这里插入图片描述

  • 当然,C 语言的格式控制符不止这些,但是这些是最常用的,新手如果能从一开始就将这些常用的printf格式控制符记牢,那么后面的格式化输入输出将是小菜一碟。

  • 光说不练是假把式,接下来用代码演示一遍。

  • 在 hello.h 文件里创建一个函数:void formatIn(void),并在main函数中进行调用。

  • 现在函数体里面编辑好如下内容:

    int num1 = 1024;long num2 = 655356;int num3 = -15;int a = 65;float num4 = 123.456;char str[24] = "Hello world\0";long num5 = 1024578964155;
  • 然后使用 %d 对 num1 和 num4 进行输出,代码如下:printf("num1=%d,num4=%d", num1, num4);,其输出内容为:num1=1024,num4=536870912,对num1正确输出,而对num4确输出了不一样的内容。这是因为使用了 %d 即整数格式控制符之后,系统会用整数的格式去解释参数,而num4不是整数格式,而是实数格式,而实数格式在计算机的实现方式与整数格式是不一样的,有兴趣的同学可以参考这篇博客:。

  • 接着使用 %5d 对 num1 和 num2 进行输入,代码:printf("num1=%5d, num2=%5d\n", num1, num2);,其输出内容num1= 1024, num2=655356,对于num1,由于位数不够进行了空格填充,而num2的输出则没有。

  • 再用%ld对num2和num5进行输出:printf("num2=%d,num5=%ld\n", num2, num5);,其结果如下:num2=655356,num5=-1918219589,num2 正确输出,num5 则变成了负数。这是因为这个控制符是长整型控制符,而C语言长整型由于我的编辑器是32位而被默认为32位,而2^32=4,294,967,296,是一个以4为开头的十位十进制数,何况实际上32位中最高位是符号位,可以表示的范围就更小了。因此,后面的编程要注意数据表示范围,免得因为溢出导致想不到的后果。

  • 接着,尝试用 %u去输出一个负数,结果如何:printf("num3=%d,num3=%u\n", num3, num3);,结果num3=-15,num3=4294967281。看到这里,有没有感到神奇?一个负数用%u输出后变成了正数,而且还是一个很大的整数,这个原因和用%d去输出num4差不多,都是计算机采取不同策略读取相同数据产生的结果。具体可以看看我的《计算机组成原理》系列博客中关于数据表示的博客。

  • 最后看看 %f与%lf的区别,printf("num4=%f,num4=%.1f\n", num4, num4);num4=123.456001,num4=123.5,可见%f是默认输出小数点后六位,而且当位数不够是后用一个后缀填充。

  • 其他几个就不一一讲了,请看完整函数代码:

    void formatIn(void){
    int num1 = 1024; long num2 = 655356; int num3 = -15; int a = 65; float num4 = 123.456; long num5 = 1024578964155; char str[24] = "Hello world\0"; // 首先体验%d格式输出 printf("num1=%d,num4=%d\n", num1, num4); //%ld printf("num2=%d,num5=%ld\n", num2, num5); // %md printf("num1=%5d, num2=%5d\n", num1, num2); // %u printf("num3=%d,num3=%u\n", num3, num3); //%f %lf printf("num4=%f,num4=%.1f\n", num4, num4); // %c printf("a=%d, a=%c\n"); // %s printf("str=%s\n", str); //%o %x printf("num2=%o, num2=%x", num2, num2);}
  • 全部输出:

    在这里插入图片描述

  • 接下来,看看格式化输入 scanf。对于scanf 的使用,要遵循一模一样原则,接下来我会给出一个正确示例,由于篇幅,我便不再像格式输出那样尝试不同格式组合会有什么效果,有兴趣的朋友请自己动手尝试。

  • 同样的,在 hello.h 中新建一个 void formatOut(void) 函数。

    void formatOut(void){
    int num1; float num2; double num3; char* str[100]; printf("请按照格式进行输入:\n"); scanf("%d,%f,%lf,%s", &num1, &num2, &num3, &str); printf("num1=%d,num2=%f,num3=%lf,str=%s", num1, num2, num3, str);}
  • 输入如下:

    在这里插入图片描述

  • 逗号是英文逗号。

3、C++ 中的输入与输出

  • 在上面已经较为系统的学习了 C 语言中的输入与输出,接下来对 C++ 中的输入与输出进行学习,有了前面的铺垫,学习这一块。会比较轻松。
  • 由于 C++ 是继承 C 语言发展而来,上面的输入与输出方法在 C++ 代码中同样适用。C++ 在继承C 语言的 I/O 方法之外,新增了流输入与流输出,其中最为常用的就是用“cout<< [data]<<endl;”进行输出,用cin>>[variable];进行输入。

3.1、I/O 函数头文件

  • C++ 在 stream 库文件中提供了cout与cin和cerr与clog两组 I/O 函数,分别是标准输入/输出流、非缓冲标准错误流和缓冲标准错误流。
  • 在 iomanip 库文件中通过所谓的参数化的流操纵器(比如 setw 和 setprecision),来声明对执行标准化 I/O 有用的服务。
  • 而在 fstream 提供用流处理文件的相关库函数。

3.2、C++ 中的基本输入与输出

  • 接下来进行代码示例。

  • 首先是标准输入流与标准输出流,即 cout 和 cin 的使用。

  • 因为我们之前使用 C++ 默认模板生成的工程项目,因此在启动文件中编辑器已经事先帮我们引入了 iostream 文件。

  • 所以我们直接在 main 函数里面编辑如下代码示例:

    // 如果在文件头部没有使用 using namespace std;// 则以下代码在使用 cout 或 cin 时请改为 std::cout 或 std::cinint t;cout << "请输入一个整数:";cin >> t;cout << "你所输入的整数为:" << t << endl;	// endl 表示换行int num;char s[50];cout << "请输入一个整数和字符串:";cin >> num >> s;cout << "你所输入的整数:" << num << ",你所输入的字符串:" << s << endl;
  • 其输出结果如下:

    在这里插入图片描述

  • 由这个例子便可以大致看出,使用 C++ 输入输出流,比 C 语言的标准输入输出函数方便的地方就在于,不同数据类型的数据可以在不用控制符的情况下就能一起输入与输出。

  • iostream 库文件除了提供上面的 cout 和 cin 外,还提供了以下方法:

    在这里插入图片描述
    在这里插入图片描述

  • 由于 cerr 和 clog 平时用得不多,便不进行代码示例,接下来重点看看 iomanip 头文件为我们提供的函数及其作用。

3.3、C++ 的 iomanip 库函数

  • iomanip 库文件中库函数,主要用于进行 C++ 的格式化输入输出,首看看该库文件提供的常用方法:
    在这里插入图片描述
  • 其中,setiosflags 的常用标志参数如下:
    在这里插入图片描述
  • 其用法例如:
    setiosflags(ios::fixed) 固定的浮点显示 setiosflags(ios::scientific) 指数表示 setiosflags(ios::left) 左对齐 setiosflags(ios::right) 右对齐 setiosflags(ios::skipws 忽略前导空白 setiosflags(ios::uppercase) 16进制数大写输出 setiosflags(ios::lowercase) 16进制小写输出 setiosflags(ios::showpoint) 强制显示小数点 setiosflags(ios::showpos) 强制显示符号

3.4、C++ 格式化输入输出示例

  • 在上面的基础上,接下来进行 C++ 格式化输入输出示例。
    // 使用之前先导入 iomanip 库文件	cout << setiosflags(ios::left | ios::showpoint);  // 设左对齐,以一般实数方式显示	cout.precision(5);       // 设置除小数点外有五位有效数字	cout << 123.456789 << endl;	cout.width(10);          // 设置显示域宽10	cout.fill('*');          // 在显示区域空白处用*填充	cout << resetiosflags(ios::left);  // 清除状态左对齐	cout << setiosflags(ios::right);   // 设置右对齐	cout << 123.456789 << endl;	cout << setiosflags(ios::left | ios::fixed);    // 设左对齐,以固定小数位显示	cout.precision(3);    // 设置实数显示三位小数	cout << 999.123456 << endl;	cout << resetiosflags(ios::left | ios::fixed);  //清除状态左对齐和定点格式	cout << setiosflags(ios::left | ios::scientific);    //设置左对齐,以科学技术法显示	cout.precision(3);   //设置保留三位小数	cout << 123.45678 << endl;
  • 输出结果如下:
    在这里插入图片描述
  • 好了,C/C++ 的数据输入与输出的相关内容就到这里了,加油!

转载地址:http://ihqgn.baihongyu.com/

你可能感兴趣的文章
常用链接
查看>>
Easyui Pagenation应用方法
查看>>
MySQL十大优化技巧
查看>>
MySQL数据库管理常用命令
查看>>
php 文件操作
查看>>
10个免费的PHP脚本资源下载网站推荐
查看>>
php正则表达式
查看>>
php自定义常量 define()函数
查看>>
PHP中文件读写操作
查看>>
PHP操作FTP-用法
查看>>
PHP面向对象v1:
查看>>
迭代开发优点
查看>>
php开发常识b_01
查看>>
php基础算法
查看>>
PHP PDO 学习笔记
查看>>
PDO存取资料库
查看>>
PDO常见用法
查看>>
curl用法
查看>>
csv文件读写操作
查看>>
Smarty模板引擎应用
查看>>