龙潭书斋 -- 358




因为标准IO都是调用系统调用实现的,所以每个标准IO都有一个与其相关联的文件描述符,可以调用fileno函数获得其描述符int fileno( FILE *stream ); 返回文件描述符 var CODE_DIVS=[{"id":"editor_a","mode":"c_cpp"}];
#读书笔记    #技术帖    #linux    #unix   
格式化输出int printf(const char *format,[argument]); int fprintf(FILE *stream,char *format,[argument]); 两个函数若成功返回输出的字符数,否则返回负值 int sprintf( char *buf, const char *format, [ argument] … ) ; int snprintf(char *buf, size_t size, const char *format, ...); 两个函数若调用成功返回存入数组buf的字符数,否则返回负值 注意的是,sprintf是不安全的,可能会造成buf的溢出,但是调用snprintf前会先清空buf,这点要注意 转换说明有四个可选部分和一个不可选部分组成:% [flags] [fldwidth] [precision] [lenmodifier] convtype flags:-      : 在字段内左对齐输出+      : 总是显示带符号转换的符号(空格)  
#读书笔记    #技术帖    #c语言    #龙潭书斋   
概述有三种方法可以定位标准IO流ftell 和 fseek 函数,这两个函数假定文件的位置可以存放在一个长整型中ftello 和 fseeko 函数,他们使用off_t类型代替了长整型fgetpos 和 fsetpos 函数,是由ISO C引入,用抽象数据类型fpos_t记录文件位置 ftell、fseek、rewindlong ftell ( FILE *stream ); 返回当前文件位置指示,调用出错返回-1L int fseek(FILE *stream, long offset, int whence); 调用成功返回0,否则返回非0值 用于二进制文件时,必须指定一个字节的offset,以及解释这种偏移量的方式 whence与lseek函数的相同:若whence是SEEK_SET, 则将该文件的偏移量设置为距文件开始处offset个字节若whence是SEEK_CUR,则将该文件的偏移量设置为其当前值加offset,offset可以为正或负若whence是SEEK_END,则将该文件的偏移量设置为文件长度加offset,offset可以为正或负对于文本文件,offset只能取两种值,0(文件起始处)或是f
#读书笔记    #技术帖    #linux    #unix   
标准IO库提供了两个函数进行二进制IO操作,与普通IO操作不同的是,二进制IO往往需要读写整个结构,一次循环处理一个字节,而不是仅仅某个字符,而如果通过调用 fputs 和 fgets 实现,由于二进制IO过程中可能会提供 null 字节而不能正确工作 size_t fread (void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp); size_t fwrite (const void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp); 定义于 <stdio.h> 头文件中,返回读或写的对象数 ptr 指向需读写对象的首地址size 为对象大小nobj 为对象个数fp 为读/写文件指针注:restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式。即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改;这样做的好处是,能帮助编译器进行更好的优化代码,生成更有效率的汇
#读书笔记    #技术帖    #linux    #unix   
非格式化IO一旦打开了流,则可以在三种不同类型的非格式化IO中进行选择,对其进行读写操作: 每次一个字符的IO 每次一行的IO 一次读或写一行,则使用 fgets 和 fputs,每行以一个换行符终止。 直接IO(二进制IO) fread 和 fwrite 函数支持直接的IO操作,每次IO读或写固定数量的对象,这两个函数常用于从二进制文件中每次读或写一个结构  每次读或写一个字符的IO1、输入函数int getc ( FILE *stream ); int fgetc ( FILE *stream ); int getchar ( void ); 定义于stdio.h头文件中,若成功则返回下一个字符,若已到达文件结尾或出错则返回EOF 区别:getchar等价于getc(stdin)getc可以被系统实现为宏,而fgetc不行,这意味着,fgetc一定是一个函数,而getc可能是一个宏,因此fgetc可以取得函数地址并作为另一个函数的参数,但fgetc的调用时长可能会长于getc 为了判断返回EOF时函数是否出错,必须调用 ferror 或 feof 函数int ferror(FILE *stream); int feof(FILE *stream); 定义于stdio.h头文件中,条件为真
#读书笔记    #linux    #unix    #c++   
打开文件可以使用三个函数中的一个打开流:FILE * fopen(const char * path,const char * mode); FILE *freopen(const char *filename,const char *type, FILE *stream); FILE * fdopen(int fildes,const char * mode); 均声明于stdio.h头文件中,若调用成功则返回文件指针,调用失败返回NULL 三个函数的区别是:fopen打开一个指定的文件freopen在一个指定的流上打开一个指定的文件,若该流已经打开,则先关闭该流。若已经定向,则清除定向。此函数一般用于将指定的文件打开为一个预定的流:标准输入、标准输出或标准失败fdopen获取一个现有的文件描述符,并使一个标准IO流与该描述符相结合。此函数通常用于由创建管道和网络通信函数返回的描述符。因为这些特殊类型的文件不能用fopen函数打开,所以需要先调用设备专用函数以获取一个文件描述符 type参数指定IO流的读写方式,ISO C规定了15种type的值 r 或 rb 为读而打开 w 或 wb 如果文件不存在则创建,若文件存在则先将文件截短至0 a 或 ab 如果文件不存在则创建,若文件存在则定位到文件尾 r+ 或 r+b 或 rb+ 为读写打开文
#读书笔记    #技术帖    #linux    #unix   
标准输出、标准输入和标准出错对一个进程预定义了三个流,并且这三个流可以自动的被进程使用,他们就是标准输入、标准输出和标准出错。通过预定义的文件指针 stdin、stdout和stderr加以引用,这三个文件指针同样定义于stdio.h中 缓冲标准IO库提供缓冲的目的是尽可能减少使用read和write的次数。标准IO提供了三种类型的缓冲:(1)全缓冲这种情况下,只有在填满标准IO缓冲区后才进行IO操作,对于驻留在磁盘上的文件通常是由标准IO库实施全缓冲的,在一个流上执行第一次流操作时,相关标准IO函数调用malloc获得需要使用的缓冲区冲洗(flush)缓冲区可以由标准IO例程自动冲洗(如缓冲区被填满时),也可以调用fflush函数冲洗一个流值得注意的是,对于标准IO,flush以为着将缓冲区中的内容写到磁盘上,而在终端驱动程序方面,flush意味着丢弃已存储在缓冲区中的数据int fflush(FILE *stream) 定义于stdio.h头文件中,调用成功返回0,否则返回EOF,如果stream为NULL,则冲洗所有输出流(2)行缓冲在这种情况下,当在输入或输出中,遇到换行符时才执行IO操作,但如果在遇到换行符前缓冲区已经被填满,则立即执行IO操作(3)不带缓冲标准IO库不对字符进行缓冲存储,所以系统很可能会一个字符一个字符地完成读写标准出错流s
#读书笔记    #技术帖    #linux    #unix   
引言不仅在UNIX上,在很多系统中都实现了标准IO库,它由ISO C标准说明。标准IO库处理很多细节,例如缓冲区的分配,以优化长度执行IO等,这使得它更加便于使用,但是如果不深入理解又会出现一些问题 大部分UNIX应用中使用标准IO库,但是标准IO库还有很多不足之处,比如由于频繁的缓冲区复制,导致运行效率的低下关于刷新,当程序交互运行时,每次读写交替会自动冲洗缓冲区 第三章中介绍的无缓冲IO是针对文件描述符的,当打开一个文件时,返回一个文件描述符,然后使用这个文件描述符来进行后续的IO操作。而对于标准IO,它们的操作是围绕流(stream)进行的,当使用标准IO库打开或创建一个文件时,我们已使一个流与一个文件相关联 流的定向 -- fwide流的定向决定了一个所读写的字符是单字节还是多字节的,可以用fwide函数设置和查询流的定向int fwide(FILE *fp, int mode); 定义于 stdio.h 和 wchar.h 头文件中,调用成功时,若流逝宽定向则返回正值,若流是字节定向则返回负值,若流是未定向则返回0 根据mode的不同,fwide执行不同的工作:若mode为负,fwide将使指定的流为字节定向若mode为正,fwide将使指定的流为宽字符
#读书笔记    #技术帖    #linux    #unix   
通常我们复制一个文件的过程是先read后write,但是,UNIX系统具有空洞文件的特殊情况,因此不能简单地使用这种方法,否则所有的空洞会被\0填充而使得目标文件比源文件大一些(因为空洞的被填充),下面是我的代码(有参考系统命令cp的源码):#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <sys/stat.h> int main () { int rfd = open ("holefile", O_RDONLY); int wfd = open ("cpholefile", O_WRONLY | O_CREAT); int res; struct stat statbuf; if (fstat(rfd, &statbuf) < 0) { perror ("fstat"); return -1; } if (statbuf.st_size <= statbuf.st_blocks * 512) {
#读书笔记    #技术帖    #linux    #unix   
每个进程都有一个当前工作目录,此目录是搜索所有相对路径名的起点,当前工作目录是进程的一个属性,那么,怎么改变当前工作目录呢? e.g.#include <stdio.h> int main () { system ("cd .."); fopen ("t", "w"); return 0; } 该程序执行后,t文件被创建在了可执行文件所在目录,可以知道,这种方法是不可行的,无法实现进程工作目录的改变,而且shell的当前工作目录也没有改变 进程可以调用chdir、fchdir两个函数更改当前工作目录int chdir (const char *path); int fchdir (int filedes); 定义于unistd.h头文件中,调用成功返回0,调用失败返回-1分别用pathname或文件描述符来指定新的当前进程工作目录,但不会改变shell的当前工作目录 内核保持有当前工作目录的信息,但是内核为每个进程只保存指向该目录v节点的指针等目录本身的信息,而不保存该目录的完整路径名,因此我们需要使用getcwd函数获取其绝对路径名char *getcwd(char *buf, size_t size); 定义于unistd
#读书笔记    #技术帖    #linux    #unix   



京ICP备15018585号