C-I/O操作函数详解
EOF: End Of File, 文字流结尾, 这里的文字流可以是文件(file), 也可以是标准输入(stdin), 它的值在任何可能出现的字符之外(-1)
先列出三种基本类型操作函数
这里面返回类型为int的基本失败后都返回EOF类型, 返回类型为指针的都返回NULL类型
1.
参数: mode表示流是用于只读、只写以及既读又写, 以及它是文本流还是二进制流, 无论(w, a)数据只能从文件的尾部写入(读可以选位置, 写只能从末尾), 如果使用附加模试("a"或"a+"), 任何写入文件数据都会被附加上去, 而文件的位置将会被忽略(用a模式打开后设置指针位置, 执行写入仍是在末尾添加) , 如果用"a+"表示该文件打开用于更新, 并且流既允许读也允许写, 但是如果你已经从该文件读了一些数据, 那么在你开始向它写入数据之前, 你必须调用其中一个文件定位函数(fseek, fsetpos, rewind), 在你向文件写入了一些数据之后, 如果你又想从该文件读取一些数据, 你首先必须调用fflush函数或者文件定位函数
FILE *fopen(char const *filename, char const *mode);打开一个特定的文件, 并把一个流和这个文件相关联
#include <stdio.h> int main(int arc, char **argv) {
char *fname = "a.txt";
FILE *fp = fopen(fname, 'r');
if (fp == NULL) {
perror(fname);
} else {
fclose(fp);
}
}
2.
FILE *freopen(char const *filename, char const *mode, FILE *stream);用于打开或者重新打开一个特定的文件流, 最后一个stream就是要打开的流, 可以是fopen函数返回的流, 也可能是标准刘stdin, stdout, stderr, 这个函数首先试图关闭这个流, 然后用指定的文件和模式重新打开这个流, 成功返回第三个参数值, 失败返回NULL
3.
int fclose(FILE *fp); 关闭流, 对于输出流, fclose函数在文件关闭之前刷新缓冲区, 如果执行成功返回零值, 否则返回EOF
4.当一个流被打开后可以用于输入和输出, 最简单形式是字符I/O操作, 字符输入是由getchar函数家族执行的
int getchar(void); //始终从标准输入读取
int getc(FILE *stream);
int fgetc(FILE *stream);
以上各个函数都从流中读取下一个字符, 并把它作为函数的返回值返回, 如果没有下个字符, 返回常量值EOF
注意: fgetc为真正的函数, getc, getchar为#define指令定义的宏, 返回的是int类型而不是char类型, 因为int型允许EOF, 假如返回char, 无法表示出EOF, 所以EOF的值必须在任何可能出现的字符范围之外
5.把单个字符写入到流中可以使用putchar函数家族
int putchar(int ch); //始终写入到标准输出流
int putc(int ch, FILE *stream);
int fputc(int ch, FILE *stream);
打印前, 函数会把这个整型参数裁剪为无符号字符类型, 所以putchar("abc")只会打印一个字符, 具体哪个字符看编译器
注意:fputc为真正的函数, putc, putchar为#define指令定义的宏, 函数失败返回EOF
6.
在读取字符的时候并不知道流的下一个字符是什么, 因此可能你所读取的字符是你要读取字符的后面一个字符, 但是不希望丢弃这个字符怎么办呢?用ungetc函数
int ungetc(int ch, FILE *stream); //把一个字符返回到流中, 类似PHP中unshift函数, 在最头部插入, 比如输入缓冲区为"abcd", 执行ungetc('z', stdin), 则输入缓冲区为"zabcd"
7.非格式化行I/O操作函数
char *gets(char *buffer);
char *fgets(char *buffer, int buffer_size, FILE *stream);
以上函数从流中读取字符, 并把他们复制到buffer中, 当读取到一个换行符并存储到缓冲区之后就不再读取, 如果缓冲区内存储的字符数达到buffer_size - 1个时它也停止读取, 一个NULL字节将被添加到缓冲区所存储数据的末尾, 使它成为一个字符串, 如果没有读取就到达了文件尾, 缓冲区则未修改, 此情况返回一个NULL指针, 否则返回FILE, 这个返回值通常只用于检查是否到达了文件尾
gets与fgets不同的是当gets读取一行输入时, 它并不在缓冲区中存储结尾的换行符
int puts(char const *buffer);
int fputs(char const *buffer, FILE *stream);
buffer必须是一个字符串, 它的字符被写入到流中, 这个字符串预期以NULL结尾, 所以函数没有缓冲区长度参数, 也就是说fgets类函数每次读取一行, 而fputs却既可以一次写入一行, 也可以写入多行, 如果写入时出现错误就返回EOF, 否则返回一个非负值
puts与fputs不同的是当puts写入一行字符串时, 它在字符串写入之后向输出再添加一个换行符
8.格式化行I/O操作函数
int scanf(char const *format, ...); 从标准输入流中读取
int sscanf(char const *string, char const *format, ...); 从字符串中读取
int fscanf(FILE *stream, char const *format, ...); 从给定的流中读取
当格式化字符串(format)达到末尾或者读取的输入不在匹配格式字符串所指定的类型的时候输入就停止, 任何一种情况下都返回被转换的输入值的数目, 如果在输入值被转换之前文件就到达尾部, 函数就返回常量值EOF
为了让这些函数正常运行, 指针参数的类型必须是对应格式代码的正确类型!函数无法验证它们的指针参数是否为正确的类型, 所以函数就假定它们是正确的, 如果指针参数类型不正确, 那么结果就是垃圾, 也就是说根据format的类型来运行指针所指向的值
除了%c以外(包括%s)的说明符会自动跳过输入项之前的空格, 而%c不会跳过任何字符
输入多个整数时, 可用空格或回车作为分隔符, 输入多个字符、整数与字符混合时, 不能用空格做为分隔符
scanf("%[*][宽度length][限定符u|h|l][格式化代码]", ...);
或scanf("%[A-Z]", str);或scanf("%[ABC]", str), 比如scanf("%50[^\n]", str); 这样可以输入带空格的字符串
由此可见format主要由四部分组成
*: 读指定类型的数据但不保存 scanf("%d %*c %d", &x, &y);
宽度: 只截取输入length个字符做转换, 没给出宽度函数就连续读入字符知道遇见输入中的空白字符 scanf("%2d%4d", &a, &b);输入"12345678"则a为12, b为3456
限定符: l, h等说明这是长整型或短整型或double类型等, 方便移植
格式化代码: c, s, d, x等
注意:
没有精度控制 比如scanf("%2.2f", &f);是非法的
C编译在碰到空格, TAB, 回车或非法数据(如对"%d"输入"12A"时, A即为非法数据)时即认为该数据(一个变量)结束
如果缓冲区里有数据就不会提示用户输入了!感受下面的例子
#include <stdio.h> int main(int argc, char **argv) {
int a = ;
int b = ;
int c = ;
int ret = ; ret = scanf("%d%d%d", &a, &b, &c);
printf("第一次读入数量:%d\n", ret); ret = scanf("%d%d%d", &a, &b, &c);
printf("第二次读入数量:%d\n", ret); return 0;
}
造成这种原因的问题是缓冲区, 仔细分析下有好处!可以判断输入成功的熟练和清空缓冲区来解决!
9.printf家族函数
int fprintf(FILE *stream, char const *format, ...); //将结果送到指定流
int printf(char const *format); //结果输出送到标准输出
int sprintf(char *buffer, char const *format, ...); //存储到指定的buffer缓冲区中, 而不是写入到流中
C-I/O操作函数详解的更多相关文章
- OpenGL的glPushMatrix和glPopMatrix矩阵栈顶操作函数详解
OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这种变换实现的原理是又通过矩阵进行操作的.opengl中的变换一般包括视图变换.模型变换.投影变换等,在每次变换后,opengl将会呈 ...
- c语言文件操作函数详解
一.文件操作注意点: 1 打开文件时,如果打开方式加“+”,表示该文件可以“写” ; 2 退出程序一般用exit函数,正常退出参数为0,非正常退出参数为正零值 ; 3 文件的读写操作:按字符.字符串. ...
- C-常用字符串操作函数详解
//使用字符串操作应时刻注意字符串或者数组长度!!避免溢出!! 1. size_t strlen(char const *str); //计算字符串长度, 注意返回size_t类型的值, 即unsig ...
- Linux C popen()函数详解
表头文件 #include<stdio.h> 定义函数 FILE * popen( const char * command,const char * type); 函数说明 popen( ...
- Netsuite Formula > Oracle函数列表速查(PL/SQL单行函数和组函数详解).txt
PL/SQL单行函数和组函数详解 函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数主要分为两大类: 单行函数 ...
- CreateFile函数详解
CreateFile函数详解 CreateFile The CreateFile function creates or opens the following objects and returns ...
- javascript 函数详解2 -- arguments
今天我们接着上篇文章来继续javascript函数这个主题.今天要讲的是函数对像中一个很重要的属性--arguments. 相关阅读: javascript 函数详解1 -- 概述 javascrip ...
- ThinkPHP函数详解:session方法
ThinkPHP函数详解:session方法 Session方法用于Session 设置.获取.删除和管理操作. Session 用于Session 设置.获取.删除和管理操作 用法 sessi ...
- fork()函数详解
linux中fork()函数详解(原创!!实例讲解) (转载) 一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程 ...
随机推荐
- iptables只允许指定ip地址访问指定端口
首先,清除所有预设置 iptables -F#清除预设表filter中的所有规则链的规则 iptables -X#清除预设表filter中使用者自定链中的规则 其次,设置只允许指定ip地址访问指定端口 ...
- Kafka broker配置介绍 (四)
这部分内容对了解系统和提高软件性能都有很大的帮助,kafka官网上也给出了比较详细的配置详单,但是我们还是直接从代码来看broker到底有哪些配置需要我们去了解的,配置都有英文注释,所以每一部分是干什 ...
- C语言:通过指针对字符串进行拼接
// // main.c // Pointer_stringcat // // Created by ma c on 15/8/2. // Copyright (c) 2015年 bjsxt. ...
- 混沌数学之Baker模型
相关DEMO参见:混沌数学之离散点集图形DEMO 相关代码: // http://wenku.baidu.com/view/ac9b57ea172ded630b1cb65b.html class Ba ...
- super-pow
// https://discuss.leetcode.com/topic/50489/c-clean-and-short-solution class Solution { ; int powMod ...
- Informatica 常用组件Filter之一 概述
转换类型:已连接.主动 过滤器转换允许您过滤映射中的行.通过过滤器转换从源转换传递所有的行,然后为转换输入过滤条件.所有过滤器转换中的端口均为输入/输出端口,只有符合条件的行才能通过过滤器转换. 在某 ...
- HTML中显示特殊字符,如尖括号 “<”,">"等等
这几天,做个网页,之后进行解析,总是出错.最后发现是因为错误的使用了尖括号 “<”,">". 如下面的html代码: <body> 显示:<inpu ...
- Eclipse 中java跨工程调用类
在Eclipse中,有时候需要跨工程调用其他工程中的方法.如下面有两个Java Project : 如果要在A工程中调用B工程中的类,可以将B工程添加到A工程中: A---- >Build Pa ...
- GO语言基础语法
1. Go项目的目录结构 一般的,一个Go项目在GOPATH下,会有如下三个目录: project --- bin --- pkg --- src 其中,bin 存放编译后的可执行文件:p ...
- NGUI诡异的drawCall
看了很多关于NGUI drawCall的文章,见得比较多的一个观点是:一个 Atlas 对应一个Drawcall. 好奇心下做了个demo,两个panel中只用到一个Atlas,却产生了10个draw ...