C基础——文件I/O(2)

## 1、fprintf()、fscanf()和rewind() ```C int fprintf(FILE*, const char* format, [待打印项...]); ``` 第1个参数通过文件指针指定输出位置;第2个参数是格式化字符串;第3个参数可选 ```C int fscanf(FILE*, const char* format, 待输入项的地址); ``` ```C void rewind(FILE*); ``` rewind()接收文件指针,使程序返回到文件的起始位置 ## 2、随机访问:fseek()和ftell() ```C int fseek(FILE*, long, int); ``` 第1个参数指向已经被fopen()打开的待查找的文件; 第2个参数是***偏移量***,表示从起始位置开始要移动的距离,必须是long类型的值,相对于当前位置,正值为向后偏移,负值为向前偏移,0表示不移动 第3个参数是模式,确定起始位置,定义在stdio.h中 |模式|偏移量的起始位置| |-|-| |SEEK_SET|文件开始处| |SEEK_CUR|当前位置| |SEEK_END|文件末尾| ---- 旧的实现可能缺少这些宏定义,可以使用数值0L、1L、2L分别表示这3种模式 ---- 如果正常,fseek()返回值为0,如果出现错误,返回值为-1 ```C long ftell(FILE*); ``` 接收一个文件指针,返回值是long类型,返回文件指针的***当前位置***距离文件***起始位置***的***字节数***,文件的第1个字节与起始位置的距离为0, ANSI C规定,此定义只适用于以二进制模式打开的文件 ```C #include int main(void) { FILE* fp; char ch; fp = fopen("mytest", "w+"); fprintf(fp, "abcdefg"); fseek(fp, 0L, SEEK_SET); //将fp定位至文件开头 ch = getc(fp); printf("%c\n",ch); // ch = 'a'; fseek(fp, 1L, SEEK_SET); //将fp从文件开头向后偏移一个字节 ch = getc(fp); printf("%c\n",ch); // ch = 'b'; fseek(fp, 0L, SEEK_CUR); //将fp定位至当前位置 ch = getc(fp); printf("%c\n",ch); // ch = 'c'; printf("%ld\n", ftell(fp)); // 输出结果为 3,即,fp距离文件开头3个字节 return 0; } ``` ## 3、二进制模式与文本模式 对于UNIX系统,只有一种文件格式,所以不需要进行特殊的转换。 对于其它系统,二进制模式的文件读写可能与文本模式有所不同,所以在读写时要注意两者之间的区别。 例如,在MS_DOS中,编辑器以CTRL+Z标记文本文件的结尾。当以文本模式打开这些文件的时候,C可以识别这个文件结尾标记。但是,在以二进制模式打开这些文件时,CTRL+Z被当做是可以打印的字符,而真正的文件结尾标记在该字符的后面。 此外,在MS_DOS中,使用\r\n组合来表示文本文件的换行符。以文本模式打开这些文件,C会将\r\n自动转换为\n。但以二进制模式打开这些文件时,程序看到的就是\r\n,不会进行转换。 ftell函数在文本模式和二进制模式中的工作方式不同。 ### 4、可移植性 为了确保可移植性,ANSI C有以下规定 ***第一***,在二进制模式中,实现不必支持SEEK_END模式。替代方法是,从文件开始处逐个字符读取文件直到文件结尾。C预处理器的条件编译指令提供了一种系统方法来处理这种情况 ***第二***,在文本模式中,只保证以下行为 |函数调用|效果| |-|-| |fseek(file, 0L, SEEK_SET)|将文件指针定位至文件开始处| |fseek(file, 0L, SEEK_CUR)|将文件指针定位至当前位置| |fseek(file, 0L, SEEK_END)|将文件指针定位至文件结尾| |fseek(file, ftell-pos, SEEK_SET)|将文件指针定位至,到距离文件开始处ftell-pos的位置。ftell-pos是ftell()的返回值| ## 5、fgetpos()和fsetpos()函数 ```C int fgetpos(FILE* restrict stream, fpos_t* restrict pos); ``` fpos_t(file position type):文件定位类型,可以根据除数组以外的他类型来定义,在文件中指定一个位置 函数功能:接收一个文件指针,并将文件指针当前位置距离文件起始位置偏移的字节数存入pos指向的对象 成功返回0,失败返回非0 ```C int fsetpos(FILE* stream, const fpos_t* pos); ``` 以文件起始位置为基点,偏移pos个字节,确定文件指针在文件中的位置 成功返回0,失败返回非0 ```C //简单示例 #include int main(void) { FILE* fp; fpos_t position; fp = fopen("test", "w+"); fgetpos(fp, &position); //#1,将指针fp在文件test中当前位置距离test起始位置的偏移量存入position中 fputs("Hello World!\n", fp); //#2 fsetpos(fp, &position); //#3 利用position的值,来调整指针fp在文件中的位置 fputs("你好,世界!\n",fp); //#4 fclose(fp); return 0; } ``` 以上示例中 #1利用position记录指针fp距离文件开头的偏移量(字节数),当前指针指向文件起始位置,所以偏移量为0 执行#2后,文件指针fp在文件中的位置发生了改变, 通过#3,以文件起始位置为基点,偏移pos个字节,重新设置fp的位置,所以fp再次指向了文件开头 所以在执行了#4之后,“你好,世界”覆盖了“Hello world”
上一篇:初学C,请解惑


下一篇:Java性能调优之ArrayList与LinkedList