注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Under the bule sky

Get what I want "cause I ask for it.

 
 
 

日志

 
 

Linux标准I/O及相关函数  

2014-08-14 11:27:20|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
标准I/O库及其头文件stdio.h为底层I/O系统调用提供了一个通用的接口
Linux标准I/O及相关函数 - 戴↑Ω听歌 - ∞
 
标准I/O库的所有操作都是围绕流(stream)来进行的,在标准I/O中,流用FILE *来描述。
把流看作打开的文件,对流的操作就是对文件的操作。
流的定义:将数据的输入输出(传送过程)抽象为数据流。vi -t FILE
结构体在堆区分配存储空间,操作时由函数自动调用malloc分配得到首地址。
Linux标准I/O及相关函数 - 戴↑Ω听歌 - ∞
 


对于任意一个进程,系统默认打开了三个流:
标准输入 标准输出 标准出错
对应流指针 stdin stdout stderr
文件描述符 STDIN_FILENO STDOUT_FILENO STDERR_FILENO

对文件的操作主要有:文件的打开、读、写、关闭和定位。

一、打开文件

Linux标准I/O相关函数 - 戴↑Ω听歌 - ∞
 
(终端中输入:  man 3 fopen)查看用户手册 ,3 代表该函数为库函数
Linux标准I/O相关函数 - 戴↑Ω听歌 - ∞

这三个函数的区别是:

(1)fopen 打开路径名由pathname指示的一个文件
(2)freopen 常用于一个打开的流重新定向。比如stdout是标准输出,我们可以把它重定向到由path指定的一个文件。
(3)fdopen 取一个现存的文件描述符,并使一个标准的I/O流与该描述符相结合。

fopen函数:
功能:打开文件,获得流指针
参数: 
  path:打开文件的路径,"/home/will/text.txt" ; 字符指针argv[1] 
  mode:打开文件的方式 "r" "r+" "w" "w+" "a" "a+" 
  "r" :只读方式打开,要求文件存在 
  "r+" :读写方式打开,要求文件存在 
  "w" :以只写方式打开,如果文件不存在则创建文件;如果文件存在,则将文件内容删除,长度清0 
  "w+" :以读写方式打开,如果文件不存在则创建文件;如果文件存在,则将文件内容删除,长度清0 
  "a" :以追加写方式打开,如果文件不存在则创建文件 
  "a+" :以读写方式打开,追加写方式,如果文件不存在则创建文件 
Linux标准I/O相关函数 - 戴↑Ω听歌 - ∞
 
 返回值:
成功返回打开文件对应流指针;失败返回NULL,并且置errno

测试:
  1. #include <stdio.h>

  2. int main()
  3. {
  4.     FILE *fp;

  5.     if((fp = fopen("cyg_r.txt","r")) == NULL)
  6.     {
  7.         perror("fail to fopen");
  8.     }

  9.     printf("___________________________________\n\n");

  10.     if((fp = fopen("cyg_r .txt","r ")) == NULL)
  11.     {
  12.         perror("fail to fopen");
  13.     }

  14.     printf("___________________________________\n\n");

  15.     if((fp = fopen("cyg_w.txt","w")) == NULL)
  16.     {
  17.         perror("fail to fopen");
  18.     }

  19.     printf("___________________________________\n\n");

  20.     if((fp = fopen("cyg_w .txt","w ")) == NULL)
  21.     {
  22.         perror("fail to fopen");
  23.     }

  24.     printf("___________________________________\n\n");

  25.     if((fp = fopen("cyg_a.txt","a")) == NULL)
  26.     {
  27.         perror("fail to fopen");
  28.     }

  29.     printf("___________________________________\n\n");

  30.     if((fp = fopen("cyg_a .txt","a ")) == NULL)
  31.     {
  32.         perror("fail to fopen");
  33.     }
  34.     
  35.     return 0;
  36. }
Linux标准I/O相关函数 - 戴↑Ω听歌 - ∞

  对于r和r 文件必须存在,否则出错,而对于 w,w 和a,a 如果文件不存则会新建。

对于perror()这样的函数,使用时可能会要求包含其他一些头文件,如果不知道需要包含那个可以在终端中使用man perror 来查看:
Linux标准I/O相关函数 - 戴↑Ω听歌 - ∞



常用打开文件的写法:

#include <stdio.h>
#include <errno.h>//errno
#include <string.h>//strerror()

//./a.out newfile
int main(int argc, const char *argv[])
{
FILE *fp = NULL;

if(argc < 2)
{
fprintf(stderr,"Usage : %s filename\n",argv[0]);
return -1;
}

if((fp = fopen(argv[1],"w+")) == NULL)
{
fprintf(stderr,"fopen:%s : %s\n",argv[1],strerror(errno));
return -1;
}

fprintf(fp,"fopen %s success!",argv[1]);

return 0;
}



 二、关闭文件

Linux标准I/O相关函数 - 戴↑Ω听歌 - ∞
int fclose(FILE *fp); 
功能:关闭指定的流 fclose()调用成功返回0,失败返回EOF,并设置errno 
  注意:关闭流涉及到流对应的堆区FILE结构体空间和缓冲区空间释放, 所以不能对关闭的流进行任何操作,读写文件,包括关闭(不能重复关闭流)。
a.fclose()调用成功返回0,失败返回EOF,并设置errno
b.在该文件被关闭之前,刷新缓存中的数据。如果标准I/O库已经为该流自动分配了一个缓存,则释放此缓存。
c.当一个进程正常终止时(直接调用exit函数,或从main函数返回),则所有带未写缓存数据的标准I/O流都被刷新,所有打开的标准I/O流都被关闭
d.在调用fclose()关闭流后对流进行的任何操作,包括再次调用fclose(),其结果都将是未知的。


三、读写文件
1.按字符读写 

  int fgetc(FILE *stream); 
  功能:从指定流读入一个字符 参数: 
  stream:指定读的流 
  返回值 :成功返回读到字符ascii码;失败返回EOF,读到文件末尾,出错 
  注意,不管是出错还是到达文件尾端,函数都返回同样的值。 为了区分这两种不同的情况,可以调用ferror()或feof()来具体判断 
 
int fputc(int c, FILE *stream); 
  功能:向指定流写入指定字符 
  参数: c: 写入字符 stream: 指定流 
  返回值:成功返回写入字符ascii;失败返回EOF

#include <stdio.h>
int main(int argc, const char *argv[])
{
int c = 0;
#if 0
while(1)
{
c = fgetc(stdin);
if(c == EOF)
break;

fputc(c,stdout);
}
#else
while((c = fgetc(stdin)) != EOF)
{
fputc(c,stdout);
}

#endif
return 0;
}



2.按行读写
char *fgets(char *s, int size, FILE *stream); 功能:读入一行字符,最多读取size - 1,遇'\n'结束 参数: s :读入数据存储区域首地址 size :读入字符个数限制 stream :指定流 返回值:成功返回s;失败返回 NULL 注意,读入'\n'也会存储,最终会追加'\0'
int fputs(const char *s, FILE *stream); 功能:输出字符串,向指定文件

#include <stdio.h>
#include <string.h>

#define N 100

int main(int argc, const char *argv[])
{
char buf[N] = {0};
#if 0
while(fgets(buf,sizeof(buf),stdin) != NULL)
{
fputs(buf,stdout);
}
#endif
fgets(buf,sizeof(buf),stdin);
//去掉键盘输入的'\n'
buf[strlen(buf) - 1] = '\0';
puts(buf);

fputs(buf,stdout);
putchar('\n');

return 0;
}


3.按对象进行读写fread()/fwrite()
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 返回实际读取对象的个数 fread(读取数据存储位置首地址ptr,一个对象大小size,要求读取对象个数nmemb,指定读取数据的流fp); 实际要求读取字节数 一个对象大小 * 要求读取对象个数 size * nmemb 注意:如果读到文件结尾,没有对象可读,返回0,读到结尾,对象个数不够,读取实际个数 size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream); 返回实际写入对象的个数 fwrite(写入数据存储位置首地址ptr,一个对象大小size,要求写入对象个数nmemb,指定写入数据的流fp); 实际写入字节数 一个对象大小 * 实际写入对象个数 size * nmemb 注意: 循环读时返回值的判断问题,如果一次读取多个对象,则需要循环到读到0个对象为止。 否则会少最后一部分! 对象: 数据类型(基本类型,构造的类型) 对象的大小 : 数据类型的大小
注意:fread和fwrite也可以用来读写一般文件,但如果读写数据中没有固定结构, 要正确进行读写只能按照1个字节作为结构(以一个字节大小为一个对象大小)!否则读写数据会不完整! 注意读多少数据,写多少数据。

struct Student
{
char name[20];
char sex;
float score[3];
};
struct Student s[2];
struct Student stu[3] = {{"Lee",'m',{90.5,89.5,79.5}},
{"zhang",'f',{78.0,89.0,100.0}},
{"zhao",'f',{100,50,79.5}}};

n = fwrite(stu,sizeof(struct Student),3,fp);

n = fread(s,sizeof(struct Student),2,fp);

4.文件定位

标准IO中文件定位 
定位本质上指修改内核中文件表项中的offset值,同一文件,读写共用一个offset 读写完成后,offset会增加相应的读写字节数 
  定位:修改文件表项中的offset 
  int fseek(FILE *stream, long offset, int whence); 
  功能:定位指定的流,可实现文件中读写起点修改 
  参数: stream 指定流 
  offset 相对偏移量,如果offset < 0 向前偏移,offset > 0向后偏移 
  whence 相对偏移起点 
  SEEK_SET 以文件开头作为相对偏移起点 offset >= 0 
  SEEK_CUR 以当前位置作为相对偏移起点 offset 可正可负 
  SEEK_END 以文件结点尾作为相对偏移起点 offset 可正可负 
 返回值:成功返回0,失败返回-1,并设置errno

获取当前offset值 
  long ftell(FILE *stream); 
  功能:获取当前文件位置偏移量 
  返回值:成功返回当前offset,失败返回-1L,并置errno 
 
将文件位置指示器值置0,即定位到文件开头 
  void rewind(FILE *stream);

例如:
1.定位到文件开头 fseek(fp,0,SEEK_SET); rewind(fp); 2.定位到当前位置 fseek(fp,0,SEEK_CUR); 3.定位到结尾位置,向前10字节 fseek(fp,-10,SEEK_END); 4.从开头写了n个字节数据,相将n个字节数据读出来 n = fwrite(buf,1,100,fp); //需要将offset置为写之前的值! fseek(fp,-n,SEEK_CUR); /*fseek(fp,0,SEEK_SET);*/ fread(buf,1,n,fp);
四、格式化IO
Linux标准I/O相关函数 - 戴↑Ω听歌 - ∞
printf函数将格式化数据写到标准输出,fprintf写至指定的流,sprintf将格式化的字符输入数组buf中 。fprintf在该数组的尾端自动加一个NULL字节,但该字节不包括在返回值中。
Linux标准I/O相关函数 - 戴↑Ω听歌 - ∞

运行结果:
Linux标准I/O相关函数 - 戴↑Ω听歌 - ∞

#include <stdio.h>

#define N 100
int main(int argc, const char *argv[])
{
char buf[N] = {0};
printf("STDOUT:hello world!");
fprintf(stderr,"STDERR:Hello world!");
sprintf(buf,"STRING:hello world!");
puts(buf);
return 0;
}
  评论这张
 
阅读(9)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017