C/C++ (stdio.h)标准库详解

cstdio,在C语言中称为stdio.h。该库使用所谓的与物理设备(如键盘、打印机、终端)或系统支持的任何其他类型的文件一起操作。

在本文将会通过介绍函数参数,举出实际的简单例子来帮助大家快速上手使用函数。

目录

一、流

 二、库函数

1、File access(文件访问)

 fclose:

fflush :

fopen:

freopen:

setbuf :

setvbuf :

2、Operations on files(对文件的操作)

remove:

 rename:

 tmofile:

tmpnam:

3、Formatted input/output(格式化的输入/输出)

fprintf:

fscanf:

snprintf :

 sprintf:

sscanf:

vfprintf:

vfscanf:

vprintf:

vscanf:

vsnprintf:

vsprintf:

4、Character input/output:(字符输入/输出)

fgetc:

fgets:

 fputc:

fputs:

getc:

 getchar:

gets:

putc:

putchar:

ungetc:

5、Direct input/output(直接输入/输出)

fread:

fwrite:

6、Error-handling(错误处理)

clearerr:

feof:

ferror:

perror:

7、Types(类型)

FILE:

fpos_t:

size_t:

二、小结


一、流

        在C语言的标准库stdio.h中,流(stream)是一个抽象的概念,用于表示输入和输出流。在C语言中,流是用来处理文件输入和输出的抽象实体,它可以是标准输入流(stdin)、标准输出流(stdout)或者文件流(file stream)。

        、、stdio.h中定义了一系列函数和宏来操作流,例如fopen()用于打开文件流,fclose()用于关闭文件流,fread()和fwrite()用于读写文件流等。此外,还有一些用于控制流的函数和宏,如fflush()用于刷新输出缓冲区,feof()和ferror()用于检查文件结束符和错误标志等。

        通过使用流,程序可以方便地进行文件的输入输出操作,无论是从键盘读取输入,还是向文件写入数据,都可以通过流来实现。流的使用使得文件操作变得更加灵活和方便,同时也提供了一种统一的接口来处理输入输出操作。

        在程序运行时一般会使用以下三个流:

  1. stdin —— 标准输入流(键盘)
  2. stdout —— 标准输出流(屏幕)
  3. stderr —— 标准错误流(屏幕)

 二、库函数

1、File access文件访问

 fclose:

用于关闭文件与流的联系

/* fclose example */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  pFile = fopen ("myfile.txt","wt");
  fprintf (pFile, "fclose example");
  fclose (pFile);//成功返回0,失败返回EOF
  return 0;
}

 ----------------------------------------------------我是分割线-------------------------------------------------------------

fflush :

在C语言中,当你向文件写入数据时,数据通常首先被存储在内存中的缓冲区中,而不是立即写入文件。fflush函数可以强制将缓冲区中的数据写入文件,以确保数据被及时保存。这在某些情况下特别重要,比如在程序终止之前需要确保所有数据都已经写入文件时。

/* fflush example */
#include <stdio.h>
char mybuffer[80];
int main()
{
   FILE * pFile;
   pFile = fopen ("example.txt","r+");
   if (pFile == NULL) perror ("Error opening file");
   else {
     fputs ("test",pFile);
     fflush (pFile);    // flushing or repositioning required
     fgets (mybuffer,80,pFile);
     puts (mybuffer);
     fclose (pFile);
     return 0;
  }
}

 ----------------------------------------------------我是分割线-------------------------------------------------------------

fopen:

打开文件

FILE * fopen ( const char * filename, const char * mode )

        打开其名称在参数 filename 中指定的文件,并将其与流相关联,该流可在将来的操作中通过返回的 FILE 指针进行标识。文件名应该包含要打开的文件的名称的 C 字符串。其值应遵循运行环境的文件名规范。
        对流执行的操作以及如何执行这些操作由 mode 参数定义。

以下为mode参数:

 返回值:如果文件已成功打开,该函数将返回指向 FILE 对象的指针,该对象可用于在将来的操作中标识流。否则,将返回 null 指针。

/* fopen example */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  pFile = fopen ("myfile.txt","w");
  if (pFile!=NULL)
  {
    fputs ("fopen example",pFile);
    fclose (pFile);
  }
  return 0;
}

 ----------------------------------------------------我是分割线-------------------------------------------------------------

freopen:

在C语言中,freopen()函数用于重新指定一个已经打开的文件流的文件名和访问模式。这个函数可以用来重新定向一个已经打开的文件流,从而改变该文件流对应的文件。

FILE * freopen ( const char * filename, const char * mode, FILE * stream )

filename:要打开的文件名。
mode:打开方式,同fopen。
File:一个FILE型指针,可以是stdin(标准输入)或stdout(标准输出)。

使用freopen()函数可以实现一些文件操作的功能,例如:

  • 重新打开一个文件,从而关闭当前的文件流并将其重新指向另一个文件。
  • 改变文件流的访问模式,例如从只读模式改为只写模式。

        总之,freopen()函数提供了一种方便的方式来重新指定一个已经打开的文件流,从而改变其对应的文件和访问模式。 

 ----------------------------------------------------我是分割线-------------------------------------------------------------

setbuf :

用于为流指定缓冲区,可以提高输入/输出操作的性能。该函数通常用于设置标准输入、标准输出或标准错误流的缓冲区。它接受三个参数:正在设置缓冲区的流、指向缓冲区的指针和缓冲区的大小。setbuf函数对于优化输入/输出操作的性能特别有用,特别是在处理大量数据时。

void setbuf ( FILE * stream, char * buffer )

 FILE* stream:指向标识打开流的 FILE 对象的指针

buffer :用户分配的缓冲区。长度至少为 BUFSIZ 字节。或者,可以指定 null 指针来禁用缓冲。

/* setbuf example */
#include <stdio.h>

int main ()
{
  char buffer[BUFSIZ];
  FILE *pFile1, *pFile2;

  pFile1=fopen ("myfile1.txt","w");
  pFile2=fopen ("myfile2.txt","a");

  setbuf ( pFile1 , buffer );
  fputs ("This is sent to a buffered stream",pFile1);
  fflush (pFile1);

  setbuf ( pFile2 , NULL );
  fputs ("This is sent to an unbuffered stream",pFile2);

  fclose (pFile1);
  fclose (pFile2);

  return 0;
}

        在此示例中,打开两个文件进行写入。与文件 myfile1.txt 关联的流设置为用户分配的缓冲区;对它执行写入操作;数据在逻辑上是流的一部分,但在调用 fflush 函数之前,它尚未写入设备。
示例中与文件 myfile2.txt 关联的第二个缓冲区设置为无缓冲,因此后续输出操作将尽快写入设备。
但是,一旦文件关闭,缓冲流和无缓冲流的最终状态是相同的(关闭文件会刷新其缓冲区)。

  ----------------------------------------------------我是分割线------------------------------------------------------------

setvbuf :

用于设置文件流的缓冲方式,使用 setvbuf 可以控制文件流的缓冲行为,这对于低级 I/O 或对性能有严格要求的程序非常有用。

int setvbuf ( FILE * stream, char * buffer, int mode, size_t size )

参数说明:

  • stream:指向 FILE 对象的指针,该 FILE 对象指定了要更改其缓冲区的流。
  • buffer:指向用户提供缓冲区的指针。如果这个参数是 NULL,则库函数会为流自动分配一个缓冲区。
  • mode:指定缓冲区的模式。有效的模式有:
    • _IONBF:关闭缓冲。
    • _IOFBF:完全缓冲。
    • _IOLBF:行缓冲。
  • size:指定缓冲区的大小。如果该值为 0,则库函数将使用一个实现定义的值。

详细mode:

返回值:如果成功,函数返回 0;否则,返回一个非零值。

/* setvbuf example */

#include <stdio.h>

int main ()
{
  FILE *pFile;

  pFile=fopen ("myfile.txt","w");

  setvbuf ( pFile , NULL , _IOFBF , 1024 );

  // File operations here

  fclose (pFile);

  return 0;
}

        在此示例中,将创建一个名为 myfile.txt 的文件,并为关联的流请求 1024 字节的完整缓冲区,因此,只有在每次填充 1024 字节缓冲区时,才应将输出到此流的数据写入文件。

2、Operations on files(对文件的操作)

remove:

删除文件

int remove ( const char * filename );

参数说明:

const char * filename:文件名

返回值:如果文件已成功删除,则返回零值。失败时,将返回非零值

#include <stdio.h>

int main ()
{
  if( remove( "myfile.txt" ) != 0 )
    perror( "Error deleting file" );
  else
    puts( "File successfully deleted" );
  return 0;
}

----------------------------------------------------我是分割线------------------------------------------------------------

 rename:

将 oldname 指定的文件或目录的名称更改为 newname

int rename ( const char * oldname, const char * newname );

返回值:如果文件重命名成功,则返回零值。失败时,将返回非零值。

#include <stdio.h>

int main ()
{
  int result;
  char oldname[] ="oldname.txt";
  char newname[] ="newname.txt";
  result= rename( oldname , newname );
  if ( result == 0 )
    puts ( "File successfully renamed" );
  else
    perror( "Error renaming file" );
  return 0;
}

 ----------------------------------------------------我是分割线------------------------------------------------------------

 tmofile:

打开临时文件。创建一个临时二进制文件,打开以供更新(“wb+”模式,有关详细信息,请参见 fopen),其文件名保证与任何其他现有文件不同。当流关闭 (fclose) 或程序正常终止时,创建的临时文件会自动删除。如果程序异常终止,是否删除文件取决于具体的系统和库实现。

FILE * tmpfile ( void )

返回值:如果成功,该函数将返回指向创建的临时文件的流指针。失败时,返回 NULL

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

int main ()
{
  char buffer [256];
  FILE * pFile;
  pFile = tmpfile ();

  do {
    if (!fgets(buffer,256,stdin)) break;
    fputs (buffer,pFile);
  } while (strlen(buffer)>1);

  rewind(pFile);

  while (!feof(pFile)) {
    if (fgets (buffer,256,pFile) == NULL) break;
    fputs (buffer,stdout);
  }

  fclose (pFile);
  return 0;
}

----------------------------------------------------我是分割线------------------------------------------------------------

tmpnam:

生成临时文件名。返回一个字符串,其中包含与任何现有文件的名称不同的文件名,因此适合安全地创建临时文件,而不会有覆盖现有文件的风险。

char * tmpnam ( char * str );

参数:

        指向字符数组的指针,其中建议的临时名称将存储为 C 字符串。此数组的建议大小至少为 L_tmpnam 个字符。或者,可以指定一个 null 指针来使用内部静态数组来存储建议的临时名称,其指针由函数返回。

 返回值:

    成功后,指向包含临时文件建议名称的 C 字符串的指针:

  • 如果 str 是 null 指针,则指向内部缓冲区 (其内容至少保留到下次调用此函数) 。
  • 如果 str 不是 null 指针,则返回 str

如果函数无法创建合适的文件名,它将返回一个 null 指针。

#include <stdio.h>

int main ()
{
  char buffer [L_tmpnam];
  char * pointer;

  tmpnam (buffer);
  printf ("Tempname #1: %s\n",buffer);

  pointer = tmpnam (NULL);
  printf ("Tempname #2: %s\n",pointer);

  return 0;  
}

----------------------------------------------------我是分割线------------------------------------------------------------

3、Formatted input/output(格式化的输入/输出)

fprintf:

按格式指向的 C 字符串写入。如果 format 包含格式说明符(以 % 开头的子序列),则格式后面的附加参数将格式化并插入到生成的字符串中,以替换它们各自的说明符

int fprintf ( FILE * stream, const char * format, ... );

参数:

FILE*stream:指向标识输出流的 FILE 对象的指针。

const char * format:要输入的字符串(类似printf可以在字符串中规定占位符

字符串后:每个参数都包含一个值,用于替换格式字符串中的格式说明符,这些参数的数量至少应与格式说明符中指定的值数一样多。类似printf与字符串中的占位符对应,具体请看举例理解。

返回值:
成功后,将返回写入的字符总数。
如果发生写入错误,则设置错误指示符 (ferror) 并返回负数。

/* fprintf example */
#include <stdio.h>

int main ()
{
   FILE * pFile;
   int n;
   char name [100];

   pFile = fopen ("myfile.txt","w");
   for (n=0 ; n<3 ; n++)
   {
     puts ("please, enter a name: ");
     gets (name);
     fprintf (pFile, "Name %d [%-10.10s]\n",n+1,name);
   }
   fclose (pFile);

   return 0;
}

----------------------------------------------------我是分割线------------------------------------------------------------

fscanf:

中读取数据,并根据参数格式将其存储到其

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DevKevin

你们的点赞收藏是对我最大的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值