stdio.h中包含了声明FILE结构

struct _iobuf {
char *_ptr; //文件输入的下一个位置
int _cnt; //当前缓冲区的相对位置
char *_base; //指基础位置(应该是文件的其始位置)
int _flag; //文件标志
int _file; //文件的有效性验证
int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取
int _bufsiz; //文件的大小
char *_tmpfname; //临时文件名
};

FILE作为一种结构,用于访问一个流,如果激活了好几个流,那么每个流都有一个对应的FILE与他关联。当需要对流执行一些操作,调用一些函数,并向他们提供一个相关联的FILE参数。

对于ansi c运行时至少有三个流,标准输入stdin,标准输出stdout,标准错误stderr,他们都是指向FILE结构的指针。标准输入一般是键盘设备,输出是屏幕终端,一般错误和输出都是相同的,也可通过系统的输入\输出重定向进行指定输入输出。

$: program < source  > output

从source输入,输出到output。

流I/O总览

通过fopen函数打开一个流,指定读写模式,如果成功打开返回一个FILE *,打开失败返回NULL。

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

下面是fopen的常用模式

  读取 写入 添加
文本 r w a
二进制 rb wb ab

如果模式是a+,那么表示打开文件更新,可读可写。

fclose关闭流,关闭流可以防止文件被再次访问,保证储存于缓冲区的数据被正确的写入到文件。释放的FILE结构体,可以用于其他另外的文件。

int fclose(FILE *f);

执行成功返回0,否则返回EOF。

文本IO:

文本I/O函数包括三种基本的形式处理数据:单个字符,字符串,格式输入输出

1.字符IO:

fgetc和fputc是真正的函数,其他的都是通过#define指令定义的宏

int getchar()
/*说明:从stdin读取1个字符
返回值:成功,返回该字符;出错,返回EOF;*/ int fgetc(FILE fp)
/*说明:功能同getchar,默认从文件fp读取;
返回值:成功,返回该字符;出错,返回EOF;
可以重定向 */ int getc(FILE fp)
/*说明:功能与fgetc相同,但getc既可以被用作
函数实现,也可以被用作宏实现,并且它的编码效率
可能会更高.
可以重定向 */ int putchar(int ch)
/*说明:向stdout输出字符ch;
返回值:成功,返回该字符;出错,返回EOF*/ int fputc(int c, FILE fp)
/*说明:功能同putchar,默认向fp输出字符ch;
返回值:成功,返回该字符;出错,返回EOF */ int putc(int c , FILE fp)
/*说明:功能与fputc相同,但putc与getc一样既可能被用作
函数实现,也可能被用作宏实现,并且它的编码效率可能会更高;
可以重定向 */

下面的代码用于从命令行中读取输入,写入到文本中

#include <stdio.h>
int main()
{
char input;
//D盘新建文件写入命令行输入
FILE *file = fopen("D:/c.txt", "w");
//读取输入
while ((input = getchar()) != EOF) {
//输入q结束
if (input != 'q') {
//打印输入字符,putc和fputc储存输入字符
putchar(input);
fputc(input, file);
putc(input, file);
}else{
fclose(file);
break;
}
}
return 0;
}

执行:

打开文件D:/c.txt,每个字符被fputc和putc输出两遍

撤销字符IO

int ungetc(int character, FILE *stream);

把先前读入的字符返回到流中,这样可以重新被读取。下面的代码读入字母,遇到数字重新换行读取:

#include <stdio.h>
#include <ctype.h> int main()
{
int input; while((input = getchar()) != EOF && !isdigit(input)){
putchar(input);
} //将数字放回标准输入
ungetc(input, stdin);
puts("\n\ndigit:");
while((input = getchar()) != EOF && isdigit(input)){
putchar(input);
} return 0;
}

2.文本行(字符串) I/O

char gets(char str)
/*说明:从stdin读取字符串(不包括'n')写入到字符串str中;
返回值:成功,返回str首地址;错误,返回NULL*/ char fgets(char str, int N, FILE fp)
/*说明:默认从文件fp中读取N个字符(包括'n')写入到字符串str中,
如果实际输入字符串小于N, fgets自动添加'n',
返回值:成功,返回字符串首地址;错误或遇到EOF,返回NULL;
可以重定向 */ int puts(const char str)
/*说明:向stdout输出字符串str,然受输出一个'n',
返回值:成功,返回非负值;错误,EOF*/ int fputs(const char str, FILE fp)
/*说明:功能同puts,默认向文件fp写入字符串str;
返回值:成功,返回非负值;错误,EOF;
可以重定向 */

下面的代码用于,从标准输入读取字符串到buffer中,注意buffer的大小可能导致溢出,因为gets没有限定读入的长度。

#include <stdio.h>
#include <string.h> #define BUFFER_SIZE 100
int main()
{
char buffer[BUFFER_SIZE];
//D盘新建文件写入命令行输入
FILE *file = fopen("D:/c.txt", "w");
//读取输入,注意gets读取输入对长度没有限制,可能会造成溢出
while (gets(buffer) != NULL) {
//只输入一个q结束
if (strlen(buffer) == 1 && buffer[0] == 'q') {
fclose(file);
puts("Bye Bye");
break;
}else{
//将输入字符串打印,然后写入文件中
puts(buffer);
fputs(buffer, file);
}
} puts("------------------------------------------------");
file = fopen("D:/c.txt", "r");
//从文件中每次读取5个字符到buffer中,然后打印
while (fgets(buffer, 10, file) != NULL) {
puts(buffer);
} while (1)
; return 0;
}

 运行:

3.格式化I/O

当格式化字符串到达末尾或者读取的输入不在匹配格式字符串所指定的类型是,输入就停止,在任何情况下,被转换的输入值的数目作为函数的返回值返回,如果在任何输入值被转换之前就到达末尾,函数就返回常量EOF。

int scanf(const char format, ...)
/*说明:根据format从stdin格式化读取N个值,并输入到...
返回值:成功,返回读取的项数;出错,返回EOF */ int fscanf(FILE fp, const char format, ...)
/*说明:功能同scanf,默认从文件fp读取,
返回值:成功,返回读取的项数;出错或遇到文件尾,返回EOF */
可以重定向 */ /*int sscanf(const char buf, const char format, ...)
说明:根据format从buf格式化读取N个值,并输入到...
返回值:成功,返回读取的项数;出错,返回EOF */ int printf(const char format, ...)
/*说明:根据format格式化数据,并输出到stdout
返回值 成功,返回输出字符数;错误,返回负数; */ int fprintf(FILE fp, const char format, ...)
/*说明:功能同printf,默认向文件fp写入;
可以重定向 */ int sprintf(char buf, const char format, ...)
/*说明:根据format格式化数据,并输出到buf,
返回值:成功,返回输出字符数;错误,返回负数 */

下面的代码从文件中格式化读入,然后提取内容,格式化写入到字符串和文本中

#include <stdio.h>

#define BUFFER_SIZE 100
int main()
{
char string[100];
char tmp[100];
int num;
//D盘打开文件
FILE *readFile = fopen("D:/read.txt", "r");
FILE *writeFile = fopen("D:/write.txt", "w"); //格式化读入文件内容
while (fscanf(readFile, "%3d,,,%s", &num, &string) != EOF) {
//格式化写入字符串tmp中
sprintf(tmp, "id: %d type: %-10s\n", num, string);
printf("%s\n", tmp);
//格式化写入文件中
fprintf(writeFile, "id: %-4d type: %s\n", num, string);
} return 0;
}

read.txt文件内容:

255,,,棉衣
255,,,毛呢大衣
255,,,风衣
255,,,打底衫
255,,,情侣装
255,,,毛呢短裤
255,,,牛仔裤
255,,,加绒打底裤
255,,,小脚裤
255,,,半身裙
255,,,毛呢连衣裙
255,,,长袖连衣裙

运行:

write.txt文件内容:

id: 255  type: 棉衣
id: 255 type: 毛呢大衣
id: 255 type: 风衣
id: 255 type: 打底衫
id: 255 type: 情侣装
id: 255 type: 毛呢短裤
id: 255 type: 牛仔裤
id: 255 type: 加绒打底裤
id: 255 type: 小脚裤
id: 255 type: 半身裙
id: 255 type: 毛呢连衣裙
id: 255 type: 长袖连衣裙

C和指针 第十五章 文件I/O的更多相关文章

  1. C和指针 第十五章 二进制I/O

    二进制I/O 数据写入到文件效率最高的是用二进制形式写入,二进制输出避免了在数值转换为字符串过程中,所涉及的开销和精度损失,但而精致并非人眼所能阅读,所以这个技巧只有当数据被另一个程序按顺序读取才能使 ...

  2. C和指针 第十五章 习题

    15.8 十六进制倾印码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include & ...

  3. C和指针 第十五章 输入输出缓冲

    对于C,所有的I/O操作都只是简单的从程序移进或移出字节,这种字节流便成为流(stream),我们需要关心的只是创建正确的输出字节数据,以及正确的输入读取数据,特定的I/O设备细节都是对程序隐藏的. ...

  4. C和指针 第十五章 错误报告perror和exit

    15.1 错误报告 perror 任何一种程序都存在出错的可能,包括系统的函数库,当出现错误时,系统提示发生错误,标准库函数在一个外部整型变量中保存错误代码,然后把错误代码传给用户程序,提示错误原因. ...

  5. 《Linux命令行与shell脚本编程大全》 第十五章 学习笔记

    第十五章:控制脚本 处理信号 重温Linux信号 信号 名称 描述 1 HUP 挂起 2 INT 中断 3 QUIT 结束运行 9 KILL 无条件终止 11 SEGV 段错误 15 TERM 尽可能 ...

  6. perl5 第五章 文件读写

    第五章 文件读写 by flamephoenix 一.打开.关闭文件二.读文件三.写文件四.判断文件状态五.命令行参数六.打开管道 一.打开.关闭文件   语法为open (filevar, file ...

  7. Gradle 1.12用户指南翻译——第四十五章. 应用程序插件

    本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  8. Gradle 1.12 翻译——第十五章. 任务详述

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  9. Gradle 1.12用户指南翻译——第二十五章. Scala 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

随机推荐

  1. Spring.net 配置说明

    Spring.net使用说明   使用方法: 1.在配置文件设置Spring.net 节点  在配置节中,声明Spring.net,配置 context,objects 标签,来源(type) < ...

  2. [LeetCode] Count of Range Sum 区间和计数

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  3. [LeetCode] Same Tree 判断相同树

    Given two binary trees, write a function to check if they are equal or not. Two binary trees are con ...

  4. [LeetCode] Maximum Subarray 最大子数组

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  5. Android中基于CGroup的memory子系统HAL层分析-lmkd

    Android在内存管理上于Linux有些小的区别,其中一个就是引入了lowmemorykiller.从lowmemorykiller.c位于drivers/staging/android也可知道,属 ...

  6. FragmentTabHost简单保存状态的方法

    private View rootView;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container ...

  7. curl的登录总结

    demo1 <?php $curl=curl_init('http://www.baidu.com'); curl_exec($curl); curl_close($curl); ?> c ...

  8. xv6的作业翻译——作业1 - shell和系统调用

    Xv6的lecture LEC 1 Operating systems   L1: O/S overview L1:O/S概述   * 6.828 goals 6.828的目标   Understan ...

  9. iOS开发中遇到的一些优化手段(即时更新)

    1.UIButton的点击优化(防止用户吃饱了没事干猛点按钮) - (void)starButtonClickedBack:(id)sender { NSLog(@"我没有优化按钮点击&qu ...

  10. HibernateSessionFactory建立-使用ThreadLocal

    立即加载还是延迟加载必须要连接数据库的,而在Java中连接数据库是依赖java.sql.Connection,在hibernate中session就是Connection的一层高级封装,一个sessi ...