内容简介:标准 I/O 库(stdio)及其头文件 stdio.h 为底层 I/O 系统调用提供了一个通用的接口。这个库现在已经成为 ANSI 标准 C 的一部分。标准 I/O 库提供了许多复杂的函数用于格式化输出和扫描输入。在很多方面,你使用的标准 I/O 库的方式和使用底层文件描述符一样,需要先打开一个文件以建立一个访问路径,这个操作的返回值将作为其他 I/O 库函数的参数。在标准 I/O 库中,与底层文件描述符对应的是在启动程序时,有 3 个一、fopen 函数
标准 I/O 库(stdio)及其头文件 stdio.h 为底层 I/O 系统调用提供了一个通用的接口。这个库现在已经成为 ANSI 标准 C 的一部分。标准 I/O 库提供了许多复杂的函数用于格式化输出和扫描输入。在很多方面,你使用的标准 I/O 库的方式和使用底层文件描述符一样,需要先打开一个文件以建立一个访问路径,这个操作的返回值将作为其他 I/O 库函数的参数。在标准 I/O 库中,与底层文件描述符对应的是 流 (stream,需要注意的是这个流与 C++ 中的输入输出流不一样),它被实现为指向结构 FILE 的指针( 文件指针 )。
在启动程序时,有 3 个 文件流 是自动打开的,它们是 stdin、stdout 和 stderr ,在 stdio.h 中定义,分别代表着 标准输入、标准输出和标准错误输出 ,与底层文件描述符 0、1、2 相对应。可用的文件流数量与文件描述符一样,都是有限制的,实际的限制由头文件 stdio.h 中定义的 FOPEN_MAX 来定义,它的值至少为 8,在 Linux 系统中,通常是 16。
一、fopen 函数
用于文件和终端的输入输出,,类似于系统调用 open。调用 fopen 函数成功时,返回一个非空的 FILE * 指针,调用失败时,返回 NULL。函数原型如下:
#include <stdio.h>
FILE *fopen(const char *filename,const char *mode);
关于 FILE 结构,有:
typedef struct _iobuf{
int cnt; // 剩余字符数
char *ptr; // 下一个字符的位置
char *base; // 缓冲区的位置
int flag; // 文件访问模式
int fd; // 文件描述符
}FILE;
fopen 打开由 filename 参数指定的文件,并把它与一个文件流关联起来。mode 参数指定文件打开的方式,可以取以下的一些值:
字符串 | 说明 |
"r" 、"rb" | 以只读方式打开文件 |
"w" 、"wb" | 以写方式打开文件,并把文件长度截短为零 |
"a" 、"ab" | 以写方式打开文件,新内容追加在文件尾 |
"r+" 、"rb+" 、"r+b" | 以更新方式打开文件(读和写) |
"w+" 、"wb+" 、"w+b" | 以更新方式打开文件,并把文件长度截短为零 |
"a+" 、"ab+" 、"a+b" | 以更新方式打开文件,新内容追加在文件尾 |
其中,字母 b 表示文件是一个二进制文件而不是文本文件。另外,需要注意的是,mode 参数是一个字符串而不是一个字符,因此总是需要使用双引号 " " 括起来。
二、fread 函数
fread 函数用于从一个文件流里读取数据。调用 fread 成功时,返回成功读到缓冲区里的记录个数(不是字节数)。函数原型如下:
#include <stdio.h>
size_t fread(void *ptr,size_t size,size_t nitems,FILE *stream);
数据从文件流 stream 读到由 ptr 指向的数据缓冲区里,size 参数指定每个数据记录的长度,计数器 nitems 给出要传输的记录个数。举个例子:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int buffer[10];
int i;
int counter;
counter = fread(buffer,1,10,stdin);
printf("读取到缓冲区的记录个数为:%d\n",counter);
fwrite(buffer,sizeof(int),1,stdout);
exit(0);
}
这段代码从标准输入读取 10 个 字符到缓冲区中,然后调用 fwrite 函数将缓冲区中的前 4 个字符写到标准输出。
三、fwrite 函数
fwrite 函数从指定的数据缓冲区里取出数据记录,并把它们写到输出流中,返回成功写入的记录个数,其参数与 fread 函数的参数类似。
#include <stdio.h>
siize_t fwrite(const void *ptr,size_t size,size_t nitems,FILE *stream);
需要注意的是, 用 fwrite 写的文件在不同的计算机体系结构之间可能不具备可移植性 ,因此,不推荐把 fread 和 fwrite 用于结构化数据。演示代码如下:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
char buffer[] = "hello,my name is Linux公社www.linuxidc.com";
fwrite(buffer,1,sizeof(buffer),stdout);
exit(0);
}
测试下
[linuxidc@localhost linuxidc.com]$ ./linuxidc
输出:
hello,my name is Linux公社www.linuxidc.com
这段代码将 buffer 中的内容写入标准输出。
四、fclose 函数
fclose 函数关闭指定的文件流 stream,使所有尚未写出的数据都写出。因为 stdio 库会对数据进行缓冲,所以使用 fclose 是很重要的。如果程序需要确保数据已全部写出,则应该调用 fclose 函数。
#include <stdio.h>
int fclose(FILE *stream);
五、fflush 函数
fflush 函数的作用是把文件流里所有未写出的数据立刻写出。
#include <stdio.h>
int fflush(FILE *stream);
在 调用 fclose 函数时,隐含执行了一次 flush 操作,因此不需要再调用 fclose 之前调用 fflush。
六、fseek 函数
fseek 函数是与 lseek 系统调用对应的文件流函数。它在文件流里为下一次读写操作指定位置。当调用 fseek 成功时,返回 0,调用失败时 返回 -1 并设置 errno 指出错误。
#include <stdio.h>
int fseek(FILE *stream,long int offset,int whence);
七、fgetc、getc 和 getchar 函数
fgetc 函数从文件流里取出下一个字节,并把它作为一个字符返回(返回的是该字符的 ASCII 码)。当它到达文件尾或出现错误时,返回 EOF(在 stdio.h 中有定义: #define EOF -1)。必须通过 ferror 或 feof 来区分这两种情况。函数原型如下:
#include <stdio.h>
int fgetc(FILE *stream);// 注意,返回值是一个字符,但是这里用 int 类型来存放字符而不是用 char 类型
int getc(FILE *stream);
int getchar();
getc 函数的作用和 fgetc 函数一样,但是,getc 函数可以被实现为宏,因此:
1)getc 函数的参数不应该是具有副作用(如影响变量)的表达式,因为它可能会被计算多次;
2)fgetc 一定是一个函数,因此它的地址可以作为一个参数传递给另一个函数;而 gets 函数则不能保证其地址一定能作为一个函数指针传递给另一个函数;
3)由于 getc 函数可以被实现为宏,因此调用 getc 函数所用的时间可能会比 fgetc 要短。
getchar 函数的作用就相当于 getc(stdin),它直接从标准输入里读取下一个字符。
注意:为什么返回值是四个字节的 int 类型?
这是为了考虑文件结束标志 EOF 的取值。EOF 取值是 -1,如果用 unsigned 类型的话,显然取不到 -1;而如果用 char 类型的话,则 -1 对应的值为 0xff(C 语言中,数值以补码形式存储),但是 0xff 又可以是一个字节的 ASCII 码值(一些扩展字符的 ASCII > 127溢出时,可能会产生值为 0xff 的ASCII 码),这样用 EOF 显然就不能判断文件是否结束了,因为会把 ASCII 码值为 0xff 的字节误判为文件结束符。如果将返回值用 int 类型来存放的话,那么 EOF(也就是 -1)将会被保存为 0xffffffff,这时在读到 0xff,用 int 类型进行存储的话,就是 0x000000ff,就不会和 EOF 相冲突了。
八、fputc、putc 和 putchar 函数
fputc 函数把一个字符写到一个输出文件流中。它返回写入的值,如果失败,则返回 EOF。
#include <stdio.h>
int fputc(int c,FILE *stream);// 需要注意的是,这里的 c 其实是字符,把字符当做 int 类型而不是 char 类型
int putc(int c,FILE *stream);
int putchar(int c);
putc 函数的作用与 fputc 函数一样,但是它能被实现为一个宏。putchar 函数相当于 putc(c,stdout),它把单个字符写到标准输出。
注意: putchar 和 getchar 都是把字符当做 int 类型而不是 char 类型来使用的, 理由上面有讲。用一个例子演示一下 fgetc 和 fputc 函数的用法:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int buf;
FILE *file = fopen("linuxidc.txt","r");
if(file == NULL){
printf("fail to open the file!\n");
exit(1);
}
while((buf = fgetc(file)) != EOF){
fputc(buf,stdout);
}
fclose(file);
exit(0);
}
输出:
hello,my name is Linux公社www.linuxidc.com
2018.10.28
这段代码打开文件 hello.txt,并使用 fgetc 函数将文件中的内容一个字节一个字节地取出,同时使用 fputc 函数将该字节写到标准输出流中,直到文件结束。
九、fgets 和 gets 函数
fgets 函数从输入文件流 stream 里读取一个字符串,并存放到缓冲区中,一次��取的字符个数有限制。
#include <stdio.h>
char *fgets(char *s,int n,FILE *stream);
char *gets(char *s);
fgets 函数把读到的字符写到 s 指向的字符串里,直到:
1)遇到换行符,则停止读入字符,并将遇到的换行符一起传递给接收字符串,再加上一个表示结尾的空字节 \0;
2)已经传输了 n-1 个字符,则加上一个空字节 \0 结尾后,停止读入字符;
3)到达文件尾(EOF)。
当成功调用函数时,fgets 返回一个指向字符串 s 的指针。如果文件流已经到达文件尾,fgets 会设置这个文件流的 EOF 标识并返回一个空指针;如果调用函数出错,则 fgets 返回一个空指针并设置 errno 以指出错误的类型。
gets 函数类似于 fgets,只不过它直接从标准输入(stdin)读取数据并丢弃了遇到的换行符,它在接收字符串的尾部加上一个 null 字节、另外,需要注意的是, gets 函数并没有对传输字符的个数做限制,所以它可能会溢出自己的传输缓冲区 。因此,一般来说,推荐使用 fgets 函数来替代 gets 函数。
Linux公社的RSS地址 : https://www.linuxidc.com/rssFeed.aspx
本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-10/155051.htm
以上所述就是小编给大家介绍的《Linux C语言标准输入输出》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 2. Python中的基本输入、输出、格式化输出
- Java输入输出挂
- opencv自带例子学习-文件输入与输出
- Golang 中的格式化输入输出
- python3 第四章 - 输入与输出
- Go语言学习之路(五)输入和输出
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ajax for Web Application Developers
Kris Hadlock / Sams / 2006-10-30 / GBP 32.99
Book Description Reusable components and patterns for Ajax-driven applications Ajax is one of the latest and greatest ways to improve users’ online experience and create new and innovative web f......一起来看看 《Ajax for Web Application Developers》 这本书的介绍吧!
在线进制转换器
各进制数互转换器
RGB CMYK 转换工具
RGB CMYK 互转工具