【c语言】一些标准I/O函数

参考资料:c primer plus

目录

一、文件     

1.流(stream)和文件(file):

  (1)文件      

(2)流        

2.文件指针FILE 

二、标准I/O函数

1.int main(int argc,char*argv[])

2.exit()与return

3.fopen()与fclose() 

(1)fopen()

(2)fclose() 

2.putc()与getc()

3.fprintf()与fscanf()

(1)fprintf

(2)fscanf()

 4.fgets()和fputs()

      (1)fgets()

5.fseek()与ftell(),以及fgetpos()和fsetpos()

(1)fseek()

     (2)ftell()

(3)fgetpos()和fsetpos()

6.fwrite()和fread()

        (1)fwrite()

        (2) fread()

 7.int feof(FILE*fp)和int ferroe(FILE*fp)

8.rewind()

9.int ungetc(int c,FILE *fp)

10.fflush()

11.setvbuf()


一、文件     

1.流(stream)和文件(file):

  (1)文件      

        文件通常是磁盘或固态硬盘上一段以命名的存储区。例如:stdio.h,还有你所写的c程序。
        C语言把文件看作是一系列连续的字节,每个字节都能被单独读取。

        C 语言提供两种文件方式:文本模式和二进制模式。       

(2)流        

         是字节序列的抽象概念,例如文件、输入/输出设备、内部进程通信管道等。流提供一种向后备存储器写入字节和从后备存储器读取字节的方式。

        流是一个逻辑设备,和文件有着相同的行为。          

2.文件指针FILE 

        它是typedef定义的,如果有兴趣,可以去了解。

        它是一个结构指针,是一个新的数据类型,是一个包含文件管理数据的结构指针,在打开一个文件之前必须定义一个文件指针。






二、标准I/O函数






1.int main(int argc,char*argv[])

        argc表示argv中存放string的个数。argc的值是获取命令行参数的,一般情况下,argc的值为1(你只运行该程序,没有写入其他文件时)。

        argv是一个指针数组,它存储的是各命令行参数  。    

//这里主要说linux,因为我使用的就是linux

​
#include<stdio.h>
int main(int argc,char*argv[]){
    printf("%d\n",argc);//1
    for(int i=0;i<argc;i++){
        printf("%s\n",argv[i]);//程序名称
    }
    return 0;
}

​

        现在我们打开终端(windows则按win+r输入cmd,打开那个熟悉的黑框)。

//首先记得编译该程序,windows运行该程序
//linux找到该文件所处位置
//我这个文件叫test
//输入
   ./tese 123 hello world 

                        

        就会出现这些东西了,可以看见argc=4 ,  123,hello,world则分别是argv[1],argv[2],argv[3]

        记得是运行test,而不是test.c






2.exit()与return

        exit()函数是关闭所有打开的文件并结束程序,正常结束会传递0,异常结束程序传递其他非零值,不同退出值可用于区分退出原因:

        比如:

if((fp=(fopen(test,"r"))==NULL){//这些函数下面会讲
    exit(1)
}
if(fclose(fp)!=0){
    exit(2)
}

        如果你在一个函数中使用exit则会关闭程序,而非跳出该函数.

        而如果你在一个非main函数中使用return则会跳出该函数,在main函数中使用return则会跳出程序。

        return会将控制权交给上一级的递归。

        也就是说在main函数中return 0;

        与 exit(0);作用等同。

        stdlib.h头文件中 定义了两个变量:

        #define EXIT_SUCCESS 0
        #define EXIT_FAILURE 1

3.fopen()与fclose() 

(1)fopen()

       fopen()的作用是打开文件声明在stdio.h中

        原型为 

FILE *fopen(char *filename, *type);

        第一个参数是待打开的文件的名称,更具体地说是一个包含改文件名的字符串地址。

        第二个参数是一个字符串,制定待打开文件的模式。

​
​
模式字符串        含义
——————————————————————————————————————————————————————————————————————————————————————
"r"           打开文字文件只读
"w"           以写模式打开文件,并把先有文件长度截为0(删除文件()),如果文件不存在,则创建一新文件
"a"           以写模式打开文件,在原有文件后面添加内容, 如果文件不存在则创建一个
"r+"          以更新模式打开文件(打开一个文字文件读/写)
"w+"          以更新模式打开文件,并把先有文件长度截为0,如果文件不存在,则创建一新文件
"a+"          以更新模式打开文件,在原有文件后面添加内容, 如果文件不存在则创建一个,可以读文件,但只能在文件末尾补充

"b"           二进制文件(可以和上面每一项合用)(如:"rb","rb+")
"x"           可以和上面每一项合用,(c11)类似非x模式,但如果文件已存在或以独占模式打开文件,则会失败
—————————————————————————————————————————————————————————————————————————————————————

​

​

                

​
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char*argv[]){
    FILE *fp;

    if((fp=fopen(argv[1],"r"))==NULL){
        exit(EXIT_FAILURE);//EXIT_FAILURE是一个宏,为1
    }
    fclose(fp);//关闭文件

    return 0;
}

​

        程序成功打开文件后,fopen()将返回文件指针,其他I/O函数可以用该指针处理这个文件。

        文件指针并不指向实际的文件,而是指向一个包含文件信息的数据对象,其中包含操作文件的I/O函数所用的缓冲区信息。   

        注意:同一时间打开的文件数是有限的。      

(2)fclose() 

        fclose()的作用是关闭fp指向的文件.

        函数原型:        

fclose(FILE *fp)
    if(fclose(fp)!=0){
        exit(2);
    }//关闭文件

        fclose如果关闭成功,将返回一个0,否则返回EOF

2.putc()与getc()

          putc()和gets()与getchar()和putchar()类似,但有所不同的一点是,前者需要告诉使用哪一个文件,后者默认输入输出设备(键盘和显示屏)。

        ch=getchar()  等效于 ch=getc(stdin)

        putc(ch,stdout) 等效于 putchar(ch)

        实际上,putchar()和getchar()通过putc()和getc()定义               

3.fprintf()与fscanf()

(1)fprintf

        

将argument内各项的值,按format(格式控制字符串)所表示的格式,将数据格式为字符串的形式写入到文件指针fp指向的文件中。

        fprint()   的函数原型为

int fprintf( FILE *stream, const char *format, [ argument ]…)

     作用与printf()类似

      fprintf()是将内容输入到stream中

#include<stdio.h>
#include<stdlib.h>
int main(int argc,char*argv[]){
    FILE *fp;
    if((fp=fopen(argv[1],"w+"))==NULL){
        exit(EXIT_FAILURE);
    }
    fprintf(fp,"hello");//将“hello”发送到fp指向的文件中
    fprintf(stdout,"hello");//将“hello”发送到输出设备(显示屏)

    fclose(fp);

    return 0;
}

(2)fscanf()

       fscanf()的函数原型为:

int fscanf(FILE* stream, const char* format, [argument...]);

        从文件指针fp指向的文件中,按format中对应的控制格式读取数据,并存储在[argument...]对应的变量中;         

        fscanf 函数与 scanf 类似,只不过前者用于读取文件流的数据。

#include<stdio.h>
#include<stdlib.h>
int main(int argc,char*argv[]){
    FILE *fp;
    char s1[100];
    if((fp=fopen(argv[1],"a+"))==NULL){
        exit(EXIT_FAILURE);
    }
    fprintf(fp,"hello");//将“hello”发送到fp指向的文件中
    fprintf(stdout,"hello\n");//将“hello”发送到输出设备(显示屏)
    rewind(fp);//将光标移动回文件开头
    fscanf(fp,"%s",&s1);//将fp指向的文件的信息发送s1
    fprintf(stdout,"%s\n",s1);//将s1中信息发送到输出设备

    fclose(fp);

    return 0;
}

 4.fgets()和fputs()

      (1)fgets()

           fgets()的函数原型是:

​
char *  fgets(char * s, int n,FILE *stream);

​

         s为储存输入位置的地址,n为字符串大小,stream为指向FILE的指针(待读文件)

        fgets()函数读取输入知道第一个换行符的后面,或者读到文件结尾,或者读n-1个字符。

        fgets会在末尾添加一个“\0”使之成为一个字符串。

        fgets()在读到EOF时将返回NULL;如果没有则返回之前传给它的第一个参数指针;当n<=0 时返回NULL,即空指针;当n=1 时,返回空串""

        (2)puts()

        puts()的函数原型为:

int fputs(const char *s, FILE *stream);

         s为字符串的地址,stream为文件指针。

        该函数的作用是跟据传入地址找到的字符串写入指定的文件中。

        注意:fputs()在打印时不会在末尾加换行符。

#include<stdio.h>
#include<stdlib.h>
int main(int argc,char*argv[]){
      char s1[100];
      FILE *fp;
    if((fp=fopen(argv[1],"a+"))==NULL){
        exit(EXIT_FAILURE);
    }
    fgets(s1,100,fp);//将fp指向的文件中的字符传给s1
    fputs(s1,stdout);//s1中字符打印在stdout上(输出设备)

    return 0;

}

5.fseek()与ftell(),以及fgetpos()和fsetpos()

(1)fseek()

        函数原型:

int fseek(FILE *stream, long offset, int fromwhere);

        fseek的作用是将fopen打开的文件直接移动到任意字节处。

   第一个参数stream为文件指针
   第二个参数offset为偏移量,整数表示正向偏移,负数表示负向偏移
   第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或  SEEK_SET:
  SEEK_SET: 文件开头
  SEEK_CUR: 当前位置
  SEEK_END: 文件结尾
  其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.                         `

     (2)ftell()

        函数原型:

long ftell(FILE* stream);

        ftell的作用是获取文件流的读取位置。

#include<stdio.h>
#include<stdlib.h>

int main(int argc,char*argv[]){
    FILE *fp;
    char s1[100];
    char ch;
    long n=0;
    long count=0;
    if((fp=fopen(argv[1],"r+"))==NULL){
        exit(EXIT_FAILURE);
    }
    
    while((ch=getchar())!=EOF){
        putc(ch,fp);
    }
    fseek(fp,0L,SEEK_END);//将光标移动到文件结尾
    n=ftell(fp);//获取从文件开头到结尾的所有字节数
    fseek(fp,0L,SEEK_SET);//将光标移动到文件开头

    while((ch=getc(fp))!=EOF){
        putc(ch,stdout);
        count++;
    }

    printf("\nftell(fp)=%d\n",n);
    printf("%d char\n",count);

    fclose(fp);

    return 0;
}

        这个程序的目的是获取你一共向文件中写了多少个字符。

(3)fgetpos()和fsetpos()

        fseek()和ftell()的长度为long,但目前文件越来越大,long已无法满足需求,因此,ANSIC新增了fgetpos()和fsetpos(),这两个新定位函数采用了新类型:fpos_t类型,(file position type),但fpos_t不是基本类型,它由其他类型来定义。fpos_t类型的变量或数据对象可以在文件中指定一个位置,它不能是数组结构。

​
int fgetpos(FILE* restrict stream,fpos_t * restrict pos);
//把fpos_t类型的值放在pos指向的位置上。
//当前位置和文件开头的距离
//成功返回0,失败返回非0

int fsetp[os(FILE *stream,const fpos_t *pos);
//使用pos指向的位置上的fpos_t类型值来设置文件指针指向的偏移该值后的位置。
//成功返回0,失败返回非0
//fpos_t类型的值应该通过调用fgetpos()来获得
​

         

6.fwrite()和fread()

        (1)fwrite()

        函数原型:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

         fwrite()通常把二进制数值写入文件。

        ptr是待写入数据块的地址。

        size表示待写入的数据块的大小,单位为字节。

        nmemb表示待写入数据块的数量,每个数据块的大小为 size 字节。

        stream是指定待写入的文件。

FILE *fp;
char s1[100];
fwrite(s1,100,1,fp);//将s1的内容写入fp指向的文件

`fwrite会返回成功写入的项的数量,正常情况下就是nemmb.

        (2) fread()

        函数原型:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

ptr是待读文件数据在内存上的地址。
size – 这是要读取的数据块的大小,单位为字节。
nmemb – 这是待读入数据块的个数,每个数据块的大小为 size 字节。
stream – 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。

    char s1[100];
    fread(s1,100,1,fp);
//读取上次写入的100个字符

 7.int feof(FILE*fp)和int ferroe(FILE*fp)

        一般情况下函数返回EOF,则通常表示函数已经到达文件结尾。但是当文件读取错误时,函数也会返回EOF,为了区分这种情况,就有了这两个函数‘

        fefo()函数返回一个非0值时表示达到文件结尾,否则返回0.

        ferror()函数返回一个非0值时,表示读写错误,否则返回0.

8.rewind()

        表示返回文件开头。

函数原型

void rewind(FILE *stream);

与fseek(FILE*stream,0L,SEEK_SET)效果一样。

9.int ungetc(int c,FILE *fp)

         把c指定的字符放回输入流,当下次调用标准输出时将读取该字符。

        注意:如果放入多个字符,调用时读取方向将会与放入方向相反。

int main(){
    char s1[20]="hello world";
    char ch;
    int i=0;
    while((ch=s1[i])!='\0'){
        if(i>=6){
            ungetc(ch,stdin);
            break;
        }
        putchar(ch);
        i++;
    }
    
    ch=getc(stdin);
    putchar(ch);
    printf("\n");

    return 0;

}

        根据ungetc来说,应该输出"hello world",但实际上只输出了"hello w",我便进行了以下测试:

int main(){
    char s1[20]="hello world";
    char ch;
    int i=0;
    while((ch=s1[i])!='\0'){
        if(i>=6){
            ungetc(ch,stdin);
            break;
        }
        putchar(ch);
        i++;
    }
    
    ch=getc(stdin);
    putchar(ch);
    ch=getc(stdin);
    putchar(ch);
    if(!feof(stdin)){
        printf("error\n");
    }
    printf("\n");

    return 0;

}

         结果是还是输出“hello w”后等待输入,我猜测可能是因为标准输入流stdin无法使用ungetc放回任何字符,标准输入stdin只支持从键盘输入字符;

10.fflush()

        函数原型

int fflush(FILE* fp);

        fflush()的作用是引起输出缓冲区中所有未写入的数据,发送到fp所指定的输出文件。这个过程就是刷新缓冲区,如果fp为空指针,则刷新所有输出缓冲区。

11.setvbuf()

        函数原型:

int setvbuf(FILE * fp, char * buf, int mode, size_t size);

        它的作用是创建一个供I/O函数替换使用的缓冲区,在打开文件后且未对流操作时使用此函数。

        fp识别待处理的流。

        buf指向待使用的存储空间,如果buf值不为NULL,则必须创建一个缓存区。

        mode:

                _IOFBF:完全缓冲区(在缓冲区满时刷新);

                _IOLBF:行缓冲(在缓冲区满或者写入一个换行符时)

                _IONBF:无缓冲

操作成功返回0,否则返回非0.

    FILE*fp;
    if((fp=fopen(argv[1],"r+"))==NULL){
        fprintf(stderr,"Error");
        exit(EXIT_FAILURE);
    }
    if((setvbuf(fp,NULL,_IOFBF,2048))!=NULL){
        fprintf(stderr,"Error");
        exit(EXIT_FAILURE);
    }
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值