C和指针读书笔记(第十五章)

原创 2017年01月07日 12:24:27

1. perror()函数用于向用户报告错误,原型定义于stdio.h

void perror(char const * message);

如果message不是NULL并且指向一个非空的字符串,perror函数就打印这个字符串,后面跟一个分号和一个空格,然后打印出一条用于解释errno当前错误代码的信息。


2. exit用于终止程序的执行,原型定义于stdio.h

void exit(int status);

status参数返回给操作系统,用于提示程序是否正常完成,这个值和main函数返回的整型状态值相同。
这个函数没有返回值,当exit函数结束时,程序已经消失。


3.
绝大多数流时完全缓冲的,这就意味着“读取”和“写入”实际上是从一块被称为缓冲区的内存区域来回复制数据。用于输出流的缓冲区只有当它写满才会被刷新到设备或文件中,类似的,输入缓冲区当它为空时通过从设备或文件读取下一块较大的输入,重新填充缓冲区。
通过在printf函数后调用fflash函数可以迫使缓冲区域的数据立即写入,不管它是否已满。

printf"something");
fflash(stdout);

4. 函数名或函数家族名
1. 只用于stdin和stdout。
2. 随作为参数的流使用。
3. 使用内存中的字符串而不是流。
输入输出函数家族
① 对指针使用下标引用或间接访问操作从内存获得一个字符(或向内存写入一个字符)
② 使用strcpy函数从内存读取文本行(或向内存写入文本行)


5. 打开流
fopen函数打开一个特定的文件,并把一个流和这个文件相关联。函数原型如下

FILE *fopen(char const *name, char const *mode);

两个参数都是字符串。name是打开的文件或者设备的名字,创建文件名的规则在不同的系统中可能各不相同,所以fopen把文件名作为一个字符串,mode参数提示流是用于只读,只写还是既读又写,以及是文本流还是二进制流。下表使一些常用的模式。
常用模式
mode以r、w或者a开头,表示打开的流用于读取,写入还是添加。如果一个文件打开是用于读取的,那么它必须原先就存在。但是如果一个文件打开是用于写入的,如果它原先就存在,那么它原先的内容就会被删除。如果原先不存在,那么就创建一个新文件。如果一个打开用于添加的文件原先并不存在,那么它将被创建。如果它原先已经存在,它原先的内存并不会被删除。无论是哪一种情况,数据只能从文件的尾部写入。
fopen的值应该被检查,如果函数失败会返回一个NULL值。
freopen函数用于打开(或重新打开)一个特定的文件流。原型如下:

FILE *open(char const *filename, char const *mode, FILE *stream);

最后一个参数就是需要打开的流,它可能是一个先前从fopen函数返回的值,也可能是标准流函数stdin,stdout或stderr。这个函数首先试图关闭这个流,然后用指定的文件和模式重新打开这个流。如果打开失败,函数返回NULL。如果成功返回第三个参数值。


6. 关闭流
函数fclose关闭流。

int fclose(FILE *f);

对于输出流,fclose函数在文件关闭之前刷新缓冲区。如果执行成功,fclose返回零值,否则返回EOF。


7. 字符I/O
字符输入是由getchar函数家族执行的,原型如下:

int fgetc(FILE *stream);
int getc(FILE *stream);
int getchar(void);

需要操作的流作为参数传递给getc和fgetc,但是getchar始终从标准输入读取。每个函数从流中读取下一个字符,并把它作为函数的返回值返回。如果流中不存在更多的字符,就返回EOF。
这些函数都用于读取字符,但它们都返回int型值而不是char型值,尽管表示字符的代码本身就是小整型,但返回int型值的原因是为了返回EOF(EOF是整型)。这样EOF不会和字符重复,这些函数可以读取二进制文件。

把单个字符写入流中,可以使用putchar函数家族。

int fputc(int character, FILE *stream);
int putc(int character, FILE *stream);
int putchat(int character);

第一个参数是要被打印的字符,在打印之前,函数会把这个整型参数裁剪为一个无符号字符整型。函数失败返回EOF。

fgetc,fputc是真正的函数,但是getc,putc,getchar,putchar,都是通过#define指令定义的宏。

ungetc函数是为了撤销字符I/O。

int ungetc(int character, FILE *stream);

ungetc把一个先前读出的字符返回到流中,这样它可以在以后被重新读入。


7. 格式化的行I/O
未格式化的行I/O简单读取或写入字符串。
gets和puts函数是用于操作字符串而不是单个字符。这个特征使它们在处理一行行文本输入的程序中非常有用。函数原型如下:

char *fgets(char *buffer, int buffer_size, FILE *stream);
char *gets(char *buffer);

fgets从指定的stream中读取字符并复制到buffer中。当它读取一个换行符并存储到缓冲区后就不再读取。如果缓冲区的内存储的字符达到BUFFER_SIZE-1时它也停止读取。在这种情况下并不会出现数据丢失的情况,因为下一次调用fgets将从流的下一个字符开始读取。在任何一种情况下,一个NUL字节被添加到缓冲区所存储数据的末尾,使它成为一个字符串。
如果任何字符读取前就达到了文件尾,缓冲区就未进行修改,fgets函数返回一个NULL指针,否则fgets返回第1个参数(指向缓冲区的指针),此返回值一般用于检测是否到达文件尾。

int fputs(char const *buffer, FILE *stream);
int puts(char const *buffer);

传递给fputs的缓冲区必须包含一个字符串,它的字符被写入到流中。这个字符串预期以NUL字节结尾,所以这个函数没有一个缓冲区长度参数。这个字符串是逐字写入的:不包含一个换行符就不写入换行符。如果包含好几个换行符,所有的换行符都会被写入。因此当fgets每次都读取一个整行时,fputs可以每次写入一行的一部分也可以写入一整行或好几行。写入错误时,fputs返回常量值EOF,否则返回一个非负值。
gets和puts函数几乎和fgets和fputs相同,之所以存在是因为他们为了允许向后兼容,他们之间的一个主要的功能性区别在于当gets读取一行输入时,它并不在缓冲区中存储结尾的换行符。当puts写入一个字符串时,它在字符串写入之后想输出再添加一个换行符。

P.S. gets函数无法判断缓冲区的长度,如果长输入行被定位到短缓冲区时,多出来的字符会被写到缓冲区的后面。


8. 格式化的行I/O
格式化的行I/O执行数字和其他变量的内部和外部表示形式之间的转换。
scanf家族
每个原型的省略号表示一个可变长度的指针列表。从输入转来的值逐个存储到这些指针参数所指向的内存位置。

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

这些函数都从输入源读取字符并根据format字符串给出的格式代码对它们进行转换。fscanf的输入就是作为参数给出的流,scanf从标准输入读取,sscanf从第一个参数所给的字符串中读取字符。
当格式化字符串到达末尾或者读取的输入不再匹配格式字符串所指定的类型时,输入就停止,在任何一种情况下,被转换的输入值的数目作为函数的返回值返回。如果在任何输入值被转换之前文件就已经到达尾部,函数就返回常量值EOF。
scanf格式码
printf家族
printf函数家庭用于创建格式化的输出。函数原型如下:

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

使用printf,结果输出送到标准输出。使用fprintf,可以使用任何输出流。sprintf把它的结果作为一个NUL字节结尾的字符串存储到指定的buffer缓冲区而不是写入到流中。这三个函数的返回值是实际打印或存储的字符数。
printf格式码
printf打印的例子:P315


9.二进制I/O
数据写入文件最搞笑的方法是二进制写入。二进制输出避免了在数值转换为字符串过程中所涉及的开销和精度损失。
fread函数用于读取二进制数据,fwrite函数用于写入二进制数据。
函数原型如下:

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

buffer是一个指向用于保存数据的内存位置的指针,size是缓冲区每个原色的字节数,count是读取或写入的元素数,stream是数据读取或写入的流。
buffer参数被解释为一个或多个值的数组,count参数指定数组中有多少个值,所以读取写入一个标量时,count的值应该是1。


未完待续

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

C和指针读书笔记(第十五章)

1. perror()函数用于向用户报告错误,原型定义于stdio.hvoid perror(char const * message);如果message不是NULL并且指向一个非空的字符串,per...

读书笔记---C和指针---第十章---结构和联合

1. 2013年6月24日18:22:51 结构体的存储分配问题:同样的结构体的成员,由于在结构体中的顺序不同,最终导致此结构体所占的内存大小不同,不好的排列顺序会导致内存损失。 举例说明: #if...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

C和指针读书笔记(第五章)

1. 算术操作符:+,-,*,/,% 除了取模运算,其余几个操作符既可以用于整型值也可用于浮点型值。2. 移位操作符:<>3. 位操作符:AND(&),OR(|),XOR(^)【异或(相同为0,相异...

C和指针读书笔记(第十四章)

1. #define的用法 #define指令把一个符号名与任意的一个字符序列联系在一起#define name stuff; //每当有符号name出现在这条指令之后,预处理器就会把它替换成st...

C和指针读书笔记(第十三章)

1. 指向指针的指针 赋值 int i; int *pi; int **ppi; //把ppi初始化指向变量pi ppi = &pi; //把pi(通过ppi间接访问)初始化为指向变量i *p...

C和指针读书笔记(第十一章)

1.

C和指针读书笔记(第十章)

1.

C和指针读书笔记(第十二章)

1. 单链表P235 1.1 单链表的结构 typedef struct NODE{ STRUCT NODE *link; int value; }Node; //...

C和指针读书笔记(第十六章)

1. 整型函数 这组函数返回整型值。这个函数分为三类:算数,随机数和字符串转换。函数原型位于stdlib.h 1.1. 算数 int abs(int value); //返回参数绝对值 lon...

C和指针读书笔记——指针

1、内存中的每个位置都由一个独一无二的地址标识,内存中的每个位置都包含一个值; 2、硬件是通过地址来访问内存的; 3、不能简单地通过检查一个值的位来判断它的类型,判断一个值的类型应该根据值的使用方...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)