cstdio,在C语言中称为stdio.h。该库使用所谓的流与物理设备(如键盘、打印机、终端)或系统支持的任何其他类型的文件一起操作。
在本文将会通过介绍函数参数,举出实际的简单例子来帮助大家快速上手使用函数。
目录
3、Formatted input/output(格式化的输入/输出)
4、Character input/output:(字符输入/输出)
5、Direct input/output(直接输入/输出)
一、流
在C语言的标准库stdio.h中,流(stream)是一个抽象的概念,用于表示输入和输出流。在C语言中,流是用来处理文件输入和输出的抽象实体,它可以是标准输入流(stdin)、标准输出流(stdout)或者文件流(file stream)。
、、stdio.h中定义了一系列函数和宏来操作流,例如fopen()用于打开文件流,fclose()用于关闭文件流,fread()和fwrite()用于读写文件流等。此外,还有一些用于控制流的函数和宏,如fflush()用于刷新输出缓冲区,feof()和ferror()用于检查文件结束符和错误标志等。
通过使用流,程序可以方便地进行文件的输入输出操作,无论是从键盘读取输入,还是向文件写入数据,都可以通过流来实现。流的使用使得文件操作变得更加灵活和方便,同时也提供了一种统一的接口来处理输入输出操作。
在程序运行时一般会使用以下三个流:
- stdin —— 标准输入流(键盘)
- stdout —— 标准输出流(屏幕)
- 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:
从流中读取数据,并根据参数格式将其存储到其