C语言之IO流函数

文章目录

  • 1 IO 函数
    • 1.1 错误函数
      • 1.1.1 检测流上的错误函数ferror
      • 1.1.2 复位错误标志函数clearerr
    • 1.2 结束函数
      • 1.2.1 检测文件结束符函数feof
      • 1.2.2 清除文件缓冲区函数fflush
    • 1.3 处理文件函数
      • 1.3.1 文件的打开与关闭函数fopen,fclose
      • 1.3.2 替换文件中数据流函数freopen
      • 1.3.3 文件指针定位函数fseek
      • 1.3.4 定位流上的文件指针函数fsetpos
      • 1.3.5 返回当前文件指针位置函数ftell
      • 1.3.6 删除文件函数remove
      • 1.3.7 重命名文件函数rename
      • 1.3.8 重置文件指针函数rewind
      • 1.3.9 指定文件流的缓冲区函数setbuf,setvbuf
      • 1.3.10 创建临时文件函数tmpfile
      • 1.3.11 创建临时文件名函数tmpnam
    • 1.4 读取函数
      • 1.4.1 从流中读取字符函数fgetc
      • 1.4.2 取得当前文件的句柄函数fgetpos
      • 1.4.3 从流中读取字符串函数fgets
      • 1.4.4 从流中读取字符串函数fread
      • 1.4.5 向文件写入数据函数fwrite
      • 1.4.6 从流中读取字符函数getc
      • 1.4.7 从标准输入文件中读取字符函数getchar
      • 1.4.8 从标准输入文件中读取字符串函数gets
      • 1.4.9 格式化输入函数scanf
      • 1.4.10 向字符串写入格式化数据函数sprintf
      • 1.4.11 从缓冲区中读格式化字符串函数sscanf
      • 1.4.12 把字符退回到输入流函数ungetc
    • 1.5 输出函数
      • 1.5.1 格式化输出函数fprintf
      • 1.5.2 向流中输出字符函数fputc
      • 1.5.3 向流中输出字符串函数fputs
      • 1.5.4 格式化输入函数fscanf
      • 1.5.5 打印系统错误信息函数perror
      • 1.5.6 产生格式化输出的函数printf
      • 1.5.7 向指定流中输出字符函数putc
      • 1.5.8 向标准输出文件上输出字符putchar
      • 1.5.9 将字符串输出到终端函数puts

1 IO 函数

1.1 错误函数

1.1.1 检测流上的错误函数ferror

函数原型:int ferror(FILE *fp);
函数功能:检测流上的错误。即:检查文件在使用各种输入输出函数进行读写时是否出错。当输入输出函数对文件进行读写时出错,文件就会产生错误标志。应用这个函数,就可以检查出fp所指向的文件操作是否出错,也就是说是否有错误标志。
返回值:未出错返回值为0,否则返回非0,表示有错。

#include <stdio.h>
int main(void)
{FILE *fp;char ch;/* 以写的方式打开一个文件名为test.txt的文件 */fp = fopen("test.txt", "w");/* 错误地从fp所指定的文件中读取一个字符,并打印它*/ch = fgetc(fp);printf("%c\n",ch);if (ferror(fp)){/* 如果此操作错误,就发布错误信息*/printf("Error reading from test.txt !\n");/*复位错误标志*/clearerr(fp);}/*关闭文件*/
fclose(fp);return 0;
}

1.1.2 复位错误标志函数clearerr

函数原型:void clearerr(FILE *fp);
函数功能:复位错误标志,即:使fp所指向的文件中的错误标志和文件结束标志置0。当输入输出函数对文件进行读写出错时,文件就会自动产生错误标志,这样会影响程序对文件的后续操作。clearerr函数就是要复位这些错误标志,也就是使fp所指向的文件的错误标志和文件结束标志置0,从而使文件恢复正常。

#include <stdio.h>
int main(void)
{FILE *fp;char ch;/* 以写的方式打开一个文件名为test.txt的文件 */fp = fopen("test.txt", "w");/* 错误地从fp所指定的文件中读取一个字符,并打印它*/ch = fgetc(fp);if (ferror(fp)){/* 如果此操作错误,就发布错误信息*/printf("This is a error reading!\n");/*复位错误标志*/clearerr(fp);}/*关闭文件*/
fclose(fp);return 0;
}

注意:ferror函数与clearerr函数应该配合使用。也就是说,通过ferror函数检测出文件有错误标志后要用clearerr函数复位错误标志。

1.2 结束函数

1.2.1 检测文件结束符函数feof

函数原型:int feof(FILE *fp);
函数功能:检测流上的文件结束符,即:检测文件是否结束。应用该函数可以判断一个文件是否到了结尾。在读取一个未知长度文件时,这个函数很有用。
返回值:遇到文件结束符返回非0,否则返回0。

#include <stdio.h>
int main(void)
{FILE *stream;/* 以只读方式打开test.txt文件 */stream = fopen("test.txt", "r");/* 从文件中读取一个字符 */fgetc(stream);/*检测是否是EOF,即结束标志 */if (feof(stream))printf("Have reached the end of the file!\n");/* 关闭该文件 */fclose(stream);return 0;
}

注意:在实际应用中,feof函数很重要,利用它程序员就可以很方便地判断当前的文件是否结束,从而进行不同的处理。例如,在从一个未知长度的文件中读取信息时,就可以利用feof函数判断什么时候该文件读完。

1.2.2 清除文件缓冲区函数fflush

函数原型:int fflush(FILE *fp);
函数功能:清除一个流,即清除文件缓冲区,当文件以写方式打开时,将缓冲区内容写入文件。也就是说,对于ANSIC规定的是缓冲文件系统,函数fflush用于将缓冲区的内容输出到文件中去。
返回值:如果成功刷新,fflush返回0。指定的流没有缓冲区或者只读打开时也返回0值。返回EOF指出一个错误。

#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <io.h>
int main(void)
{FILE *stream1,*stream2;char test[20]="This is a test";char res[20];/*以写的方式打开文件test.txt*/stream1 = fopen("test.txt", "w");/*向文件写入字符串*/fwrite(test,15,1,stream1);/*以读的方式打开文件test.txt*/stream2 = fopen("test.txt", "r");/*将文件内容读入缓冲区*/if(fread(res,15,1,stream2))printf("%s",res);elseprintf("Read error!\n");fclose(stream1);fclose(stream2);getch();return 0;
}显示错误信息Read error!

第二种方式读写文件

#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <io.h>
int main(void)
{FILE *stream1,*stream2;char test[20]="This is a test";char res[20];/*以写的方式打开文件test.txt*/stream1 = fopen("test.txt", "w");/*向文件写入字符串*/fwrite(test,15,1,stream1);/*将缓冲区的内容写入文件*/fflush(stream1);/*以读的方式打开文件test.txt*/stream2 = fopen("test.txt", "r");/*将文件内容读入缓冲区*/if(fread(res,15,1,stream2))printf("%s",res);elseprintf("Read error!\n");fclose(stream1);fclose(stream2);getch();return 0;
}
显示字符串"This is a test"

第一个例子将文件打开后,指针stream1指向的是该文件的内存缓冲区,将字符串写入后也只是写到了文件的内存缓冲区中,而并没有写到磁盘上的文件中。而当以读的方式打开该文件时,该文件中的内容实际为空,也就是stream2指向的缓冲区中内容为空。因此读文件发生错误。
而第二个例子中,在写完文件后调用函数fflush,将缓冲区的内容写到文件中,这样再以读的方式打开该文件时,文件中已经存有了字符串,因此可以正常读出。
注意:如果在写完文件后调用函数fclose关闭该文件,同样可以达到将缓冲区的内容写到文件中的目的,但是那样系统开销较大。

1.3 处理文件函数

1.3.1 文件的打开与关闭函数fopen,fclose

函数原型:FILE fopen(char filename, char type); int fclose(FILE fp);
函数功能:函数fopen:打开一个流,即:打开一个文件。该函数有两个参数,filename是需要打开文件的文件名,type是打开文件的方式。函数fclose:关闭一个流,即:关闭一个文件,并释放文件缓冲区。fclose函数与fopen函数是相对的两个函数。fclose函数的参数是指向文件的指针,应用该函数用以在程序结束之前关闭文件,并释放文件缓冲区。这样可以保证文件的数据不流失。
返回值:fopenFILE类型,如果打开的文件存在,返回指向该文件的指针;如果打开的文件不存在,则在指定的目录下建立该文件打开,并返回指向该文件的指针。fclose:整型,有错返回非0,否则返回0。

文件使用方式意 义
r只读打开一个文本文件,只允许读数据
w只写打开或建立一个文本文件,只允许写数据
a追加打开一个文本文件,并在文件末尾写数据
rb只读打开一个二进制文件,只允许读数据
wb只写打开或建立一个二进制文件,只允许写数据
ab追加打开一个二进制文件,并在文件末尾写数据
r+读写打开一个文本文件,允许读和写
w+读写打开或建立一个文本文件,允许读写
a+读写打开一个文本文件,允许读,或在文件末追加数据
rb+读写打开一个二进制文件,允许读和写
wb+读写打开或建立一个二进制文件,允许读和写
ab+读写打开一个二进制文件,允许读,或在文件末追加数据
#include <string.h>
#include <stdio.h>
int main(void)
{FILE *fp;char buf[11] = "abcdefghij";/* 以写方式打开文件名为test.txt的文件 */fp = fopen("test.txt", "w");
/*把字符串写入文件中*/fwrite(&buf, strlen(buf), 1, fp);/* 关闭文件 */fclose(fp);return 0;
}

注意:用户在编写程序时应该养成及时关闭文件的习惯,如果不及时关闭文件,文件数据有可能会丢失。

1.3.2 替换文件中数据流函数freopen

函数原型:FILE freopen(char filename, char type, FILE fp);
函数功能:关闭fp所指向的文件,并将该文件中的数据流替换到filename所指向的文件中去。该函数共三个参数:第一个参数filename是文件流将要替换到的文件名路径;第二个参数type是文件打开的方式,它与fopen中的文件打开方式类似;第三个参数fp是要被替换的文件指针。
返回值:返回一个指向新文件的指针,即指向filename文件的指针。若出错,则返回NULL。

#include <stdio.h>
int main(void)
{FILE *Nfp;/* 替换标准输出文件上的数据流到新文件test.txt */if (Nfp=freopen("test.txt", "w", stdout)== NULL)fprintf(stderr, "error redirecting stdout\n");/* 标准输出文件上的数据流将会被替换到新文件中 */printf("This will go into a file.");/* 关闭标准输出文件 */fclose(stdout);/*关闭新生成的文件*/fclose(Nfp);return 0;
}

执行结果是在当前目录下生成一个文件test.txt,并将原终端的数据流"This will go into a file."重新写入test.txt文件中。

1.3.3 文件指针定位函数fseek

函数原型:int fseek(FILE *fp, long offset, int base);
函数功能:重定位流上的文件指针,即将fp指向的文件的位置指针移向以base为基准,以offset为偏移量的位置。该函数有三个参数:fp为文件指针,offset为偏移量,即位移offset个字节,base为指针移动的基准,即起始点。其中,基准base用0、1或2表示。
返回值:成功返回0,否则返回非0

在ANSI C标准指定的名字如下表 ANSI C标准指定的起始点名字,偏移量用长整型数表示。ANSI C标准规定,在数的末尾加L就表示长整型数。该函数在随机读取较长的顺序文件时是很有用的。

起始点名字数字代码
文件当前位置SEEK_CUR1
文件开始位置SEEK_SET0
文件末尾位置SEEK_END2
#include <stdio.h>
void main( void )
{FILE *fp;char line[81];int  result;/*以读写的方式打开打开名为test.txt的文件*/fp = fopen( "test.txt", "w+" );if( fp == NULL )printf( "The file test.txt was not opened!\n" );else{/*按照规定格式将字符串写入文件*/fprintf( fp, "The fseek begins here:"This is the file 'test.txt'.\n" );/*将文件指针定位到离文件头23个字节处*/result = fseek( fp, 23L, SEEK_SET);if( result )perror( "Fseek failed" );else{printf( "File pointer is set to middle of first line.\n" );/*从fp指向的文件中读取字符串*/fgets( line, 80, fp );/*显示读取的字符串*/printf( "%s", line );}fclose(fp);}
}运行结果为在屏幕上显示出以下字符串:File pointer is set to middle of first line.
This is the file 'test.txt'.

1.3.4 定位流上的文件指针函数fsetpos

函数原型:int fsetpos(FILE fp, const fpos_t pos);
函数功能:将文件指针定位在pos指定的位置上。该函数的功能与fgetpos相反,是将文件指针fp按照pos指定的位置在文件中定位。pos值以内部格式存储,仅由fgetpos和fsetpos使用。
返回值:成功返回0,否则返回非0。

#include <stdio.h>
void main( void )
{FILE   *fp;fpos_t pos;char   buffer[50];/*以只读方式打开名为test.txt的文件*/if( (fp = fopen( "test.txt", "rb" )) == NULL )printf( "Trouble opening file\n" );else{/*设置pos值*/pos = 10;/*应用fsetpos函数将文件指针fp按照pos指定的位置在文件中定位*/if( fsetpos( fp, &pos ) != 0 )perror( "fsetpos error" );else{/*从新定位的文件指针开始读取16个字符到buffer缓冲区*/fread( buffer, sizeof( char ), 16, fp );/*显示结果*/printf( "16 bytes at byte %ld: %.16s\n", pos, buffer );}}fclose( fp );
}显示结果:16 bytes at byte 10: test for testing 。

1.3.5 返回当前文件指针位置函数ftell

函数原型:long ftell(FILE *fp);
函数功能:返回当前文件指针的位置。这个位置是指当前文件指针相对于文件开头的位移量。
返回值:返回文件指针的位置,若出错则返回–1L。

#include <stdio.h>
int main(void)
{FILE *fp;fp = fopen("test.txt", "w+");/*按照格式要求将字符串写入文件*/fprintf(fp, "This is a test");/*读出文件指针fp的位置*/printf("The file pointer is at byte %ld\n", ftell(fp));fclose(fp);return 0;
}

注意:ftell函数的返回值实际上就是该文件的长度。在实际的应用中,函数ftell常用来计算文件的长度。

1.3.6 删除文件函数remove

函数原型:int remove(char *filename);
函数功能:删除以filename为文件名的文件。该函数的参数为欲删除文件的文件名,如果是单纯的文件名,就表明删除当前文件夹下的文件,否则要写明文件的路径。
返回值:成功删除文件返回0,否则返回-1。

#include <stdio.h>
void main()
{if( remove( "test.txt" ) == -1 )perror( "Could not delete test.txt!!" );elseprintf( "Deleted test.txt \n" );
}

注意:perror函数是按照一定格式要求向终端输出错误信息,因此,若删除文件成功,程序运行的结果为:Deleted test.txt
若删除失败,则程序运行的结果为:Could not delete test.txt!!: No such file or directory
这里,利用perror函数显示的完整的错误信息包括:用户自定义字符串,冒号,系统报错信息,换行符。

1.3.7 重命名文件函数rename

函数原型:int rename(char oldname, char newname);
函数功能:把由oldname所指的文件名改为由newname所指的文件名。该函数有两个参数,oldname为旧的文件名,newname为欲改成的新文件名。应当注意,oldname所指的文件一定要存在,newname所指的文件一定不存在。应用该函数可将一个文件的旧文件名oldname改为新文件名newname,但不能改变文件的路径。
返回值:成功返回0,出错返回-1。

include <stdio.h>
int main(void)
{if( rename("oldname.txt","newname.txt")==0)printf("Rename successful!!");elseprintf("Rename fail!!");
}

1.3.8 重置文件指针函数rewind

函数原型:void rewind(FILE *stream);
函数功能:将文件指针fp重新定位在文件开头,并清除文件的结束标志和错误标志。该函数与函数fseek功能类似,但不同的是,该函数可以清除文件的结束标志和错误标志,而函数fseek不能;另外,该函数不能像函数fseek一样返回一个值表明操作是否成功,因为该函数无返回值。
返回值:无。

#include <stdio.h>
void main( void )
{FILE *fp;int data1, data2;data1 = 1;data2 = 2;if( (fp = fopen( "test.txt", "w+" )) != NULL ){fprintf( fp, "%d %d", data1, data2 );printf( "The values written are: %d and %d\n", data1, data2 );data1=0;data2=0;rewind( fp );fscanf( fp, "%d %d", &data1, &data2 );printf( "The values read are: %d and %d\n", data1, data2 );fclose( fp );}
}
运行结果为:
The values written are: 1 and 2
The values read are: 1 and 2

注意:在应用fprintf函数向该文件写入data1,data2两个整型数后,文件指针fp会自动指向文件尾。只有再应用函数rewind、fseek才能将文件指针重新定位到文件开头,以便读取文件。本例中,将data1和data2置0的目的是为了说明应用fscanf函数向data1,data2两个变量中读入文件中的数字的结果是正确的。

1.3.9 指定文件流的缓冲区函数setbuf,setvbuf

函数原型:void setbuf(FILE fp, char buf); void setvbuf(FILE fp, char buf, int type, unsigned size);
函数功能: 这两个函数使得打开文件后,用户可以建立自己的文件缓冲区,而不必使用fopen函数打开文件时设定的默认缓冲区。 setbuf函数的定义中,参数buf指定的缓冲区大小由stdio.h中定义的宏BUFSIZE的值决定,缺省值default为512字节。而当buf为NULL时,setbuf函数将使文件I/O不带缓冲区。而对setvbuf函数,则由malloc函数来分配缓冲区。参数size指明了缓冲区的长度(必须大于0),而参数type则表明了缓冲的类型,其取值如下表: setvbuf函数中参数type的取值含义

type 值含义
_IOFBF文件全部缓冲,即缓冲区装满后,才能对文件读写
_IOLBF文件行缓冲,即缓冲区接收到一个换行符时,才能对文件读写
_IONBF文件不缓冲,此时忽略buf,size的值,直接读写文件,不再经过文件缓冲区缓冲
#include <stdio.h>
void main( void )
{char buf[BUFSIZ];FILE *fp1, *fp2;if( ((fp1 = fopen( "test1.txt", "a" )) != NULL) &&((fp2 = fopen( "test2.txt", "w" )) != NULL) ){/* 应用setbuf函数给文件流fp1指定缓冲区buf */setbuf( fp1, buf );/*显示缓冲区地址*/printf( "fp1 set to user-defined buffer at: %Fp\n", buf );/* 文件流fp2不指定缓冲区*/setbuf( fp2, NULL );/*信息提示不分配缓冲区*/printf( "fp2 buffering disabled\n" );fclose(fp1);fclose(fp2);}
}

注意:使用setbuf函数指定文件的缓冲区时,一定要在文件读写之前。一旦用户自己指定了文件的缓冲区,文件的读写就要在用户指定的缓冲区中进行,而不在系统默认指定的缓冲区中进行。函数setvbuf的用法与setbuf类似,只是它的缓冲区大小可以动态分配,由函数的参数指定,而且缓冲区的类型也可以由参数指定。

1.3.10 创建临时文件函数tmpfile

函数原型:FILE *tmpfile(void);
函数功能:创建一个临时文件。该文件以w+b(二进制读写)方式打开,当该文件被关闭时,该文件会被自动删除。
返回值:返回指向临时文件的指针,如果文件打不开则返回EOF。

#include <stdio.h>
#include <process.h>
int main(void)
{FILE *tempfp;tempfp = tmpfile();if (tempfp)printf("Temporary file be created!!\n");else{printf("Unable to create the temporary file!!\n");exit(1);}sleep(20);return 0;
}

注意:这里将程序挂起20秒的目的是为了让用户看到生成的临时文件。这是因为当程序执行完时,系统会自动删除临时文件,那样用户就感觉不到临时文件的创建了。当该程序运行时,会在当前文件夹下生成一个临时文件。 临时文件的作用是暂时存储程序运行过程中需要的数据,当程序运行完毕时,这些数据也就没有用了。

1.3.11 创建临时文件名函数tmpnam

函数原型:char tmpnam(char string);
函数功能:创建一个临时文件名,用以打开一个临时文件。
返回值:创建成功返回指向该文件名的指针,否则返回NULL。

#include <string.h>
#include <stdio.h>
main()
{char tmp[10];tmpnam(tmp);printf("The temporary name is %s\n",name);
}

注意:应用函数tmpnam生成的临时文件名是不同于任何已存在文件名的有效文件名。本函数用于给临时文件创建文件名。

1.4 读取函数

1.4.1 从流中读取字符函数fgetc

函数原型:int fgetc(FILE *fp);
函数功能:从流中读取字符,即从fp所指定的文件中取得下一个字符。这里需要注意,在每取完一个字符时fp会自动向下移动一个字节。这样编程时,程序员就不用再对fp控制了。这种功能在许多读写函数中都有体现。
返回值:返回所得到的字符,若读入错误。返回EOF

#include <string.h>
#include <stdio.h>
#include <conio.h>
int main(void)
{FILE *fp;char string[] = "This is a test";char ch;/* 以读写方式打开一个名为test.txt的文件 */fp = fopen("test.txt", "w+");/* 向文件中写入字符串string */fwrite(string, strlen(string), 1, fp);/* 将fp指针指向文件首 */fseek(fp, 0, SEEK_SET);do{/* 从文件中读一个字符 */ch = fgetc(fp);/* 显示该字符 */putch(ch);} while (ch != EOF);fclose(fp);return 0;
}

1.4.2 取得当前文件的句柄函数fgetpos

函数原型:int fgetpos( FILE stream, fpos_t pos );
函数功能:取得当前文件的指针所指的位置,并把该指针所指的位置数存放到pos所指的对象中。pos值以内部格式存储,仅由fgetpos和fsetpos使用。其中fsetpos的功能与fgetpos相反,为了详细介绍,将在后节给与说明。
返回值:成功返回0,失败返回非0,并设置errno

include <string.h>
include <stdio.h>
int main(void)
{FILE *fp;char string[] = "This is a test";fpos_t pos;/* 以读写方式打开一个名为test.txt的文件 */fp = fopen("test.txt", "w+");/* 将字符串写入文件 */fwrite(string, strlen(string), 1, fp);/* 取得指针位置并存入&pos所指向的对象 */fgetpos(fp, &pos);printf("The file pointer is at byte %ld\n", pos);/*重设文件指针的位置*/fseek(fp,3,0);/* 再次取得指针位置并存入&pos所指向的对象 */fgetpos(fp, &pos);printf("The file pointer is at byte %ld\n", pos);fclose(fp);return 0;
}

1.4.3 从流中读取字符串函数fgets

函数原型:char fgets(char string, int n, FILE *fp);
函数功能:从fp所指的文件中读取一个长度为(n-1)的字符串,并将该字符串存入以string为起始地址的缓冲区中。fgets函数有三个参数,其中string为缓冲区首地址,n规定了要读取的最大长度,fp为文件指针。
返回值:返回地址string,若遇到文件结束符或出错,返回NULL。用feof 或ferror判断是否出错。

#include <string.h>
#include <stdio.h>
int main(void)
{FILE *fp;char string[] = "This is a test";char str[20];/* 以读写的方式打开一个名为test.txt的文件 */fp = fopen("test.txt", "w+");/* 将字符串写入文件 */fwrite(string, strlen(string), 1, fp);/* 文件指针定位在文件开头*/fseek(fp, 0, SEEK_SET);/* 从文件中读一个长为strlen(string)的字符串 */fgets(str, strlen(string)+1, fp);/* 显示该字符串 */printf("%s", str);fclose(fp);return 0;
}

从文件中读一个长为strlen(string)的字符串,这里应注意第二个参数若为n,则表示从fp所指的文件中读取一个长度为(n-1)的字符串。因此,这里的参数为strlen(string)+1,表示读取一个长度为strlen(string)的字符串。把字符串读到以str为首地址的数组中。

1.4.4 从流中读取字符串函数fread

函数原型:int fread(void buf, int size, int count, FILE fp);
函数功能:从fp指向的文件中读取长度为size 的count个数据项,并将它输入到以buf为首地址的缓冲区中。此时,文件指针fp会自动增加实际读入数据的字节数,即fp指向最后读入字符的下一个字符位置。
返回值:返回实际读入数据项的个数,即count值。若遇到错误或文件结束返回0。

#include <string.h>
#include <stdio.h>
int main(void)
{FILE *fp;char str[] = "this is a test";char buf[20];if ((fp = fopen("test.txt", "w+"))== NULL){fprintf(stderr,"Cannot open output file!!\n");return 1;}/* 向文件中写入字符串数组中的数据 */fwrite(str, strlen(str), 1, fp);/* 将文件指针定位到文件开头 */fseek(fp, SEEK_SET, 0);/* 把文件中的数据读出并显示 */fread(buf, strlen(str), 1, fp);printf("%s\n", buf);fclose(fp);return 0;
}

1.4.5 向文件写入数据函数fwrite

函数原型:int fwrite(void buf, int size, int count, FILE fp);
函数功能:将buf所指向的count*size个字节的数据输出到文件指针fp所指向的文件中去。该函数与fread相对,输出数据后,文件指针fp自动指向输出的最后一个字符的下一个位置。该函数常用于分批将数据块输出到文件中。
返回值:返回实际写入文件数据项个数。

#include <stdio.h>
struct exp_struct
{int i;char ch;
};
int main(void)
{FILE *fp;struct exp_struct s;/*以写的方式打开名为test.txt的文件*/if ((fp = fopen("test.txt","wb")) == NULL){fprintf(stderr, "Cannot open the test.txt");return 1;}/*向结构体中的成员赋值*/s.i = 0;s.ch = 'A';/* 将一个结构体数据块写入文件 参数sizeof(s)是该结构体变量的大小,1指只写入文件1个数据块*/fwrite(&s, sizeof(s), 1, fp);fclose(fp);return 0;
}

1.4.6 从流中读取字符函数getc

函数原型:int getc(FILE *fp);
函数功能:从fp所指向的文件中读取一个字符。该函数与前面所讲到的fgetc作用类似。读取字符后,文件指针fp自动指向下一个字符。
返回值:返回所读的字符,若文件结束或出错返回EOF。

include <stdio.h>
int main(void)
{char ch;printf("Input a character:");/* 从标准输入文件(键盘)中读取一个字符,存入变量ch,并显示在屏幕上*/ch = getc(stdin);/*显示该字符*/printf("The character input was: '%c'\n", ch);return 0;
}
#include <stdio.h>
void main( void )
{FILE *fp;char ch;/*以写的方式打开名为test.txt的文件*/fp=fopen("test.txt","w");/*写入字符串*/fprintf(fp,"This is a test.");fclose(fp);/*再以读的方式打开名为test.txt的文件*/fp=fopen("test.txt","r");/*将文件指针指向文件开头*/fseek(fp,0L,SEEK_SET);/*应用getc函数从文件中循环读取字符并显示出来*/while(feof(fp)==0){ch=getc(fp);printf("%c",ch);}fclose(fp);return 0;
}

注意:与上例不同,上例是从标准输入文件(键盘)中读取一个字符,本例是从一般文件中读取字符,关键在于函数的参数不同。

1.4.7 从标准输入文件中读取字符函数getchar

函数原型:int getchar(void);
函数功能:从标准输入文件stdin(键盘)中读取一个字符。该函数与getc类似,但参数为空,它只能从标准输入文件中读取字符,而不能读取用户自定义的文件。getchar函数在编程时多用于接收回车、换行符。
返回值:返回所读的字符,若文件结束或出错返回-1。

include <stdio.h>
int main(void)
{int c;/* 从键盘上接收字符并显示,直到键入换行符'\n'为止 */while ((c = getchar()) != '\n')printf("%c", c);return 0;
}

1.4.8 从标准输入文件中读取字符串函数gets

函数原型:·char gets(char buf);·
函数功能:从标准输入文件 stdin(键盘) 中读取一个字符串,并把该字符串存入以buf为首地址的缓冲区中。该函数与fgets类似,但它只能从标准输入文件stdin中读取字符串,而且没有长度限制。
返回值:返回其参数,即缓冲区指针buf,若出错则返回空NULL。

#include <stdio.h>
int main(void)
{char string[30];printf("Input a string:");/*从终端输入字符串,注意不要超过30个字符*/gets(string);/*显示该字符串*/printf("The string input was: %s\n",string);return 0;
}

1.4.9 格式化输入函数scanf

函数原型:int scanf(char *format[,argument,...]);
函数功能:从标准输入设备(键盘)按照format指定的格式字符串所规定的格式,将数据输入到argument所指定的内存单元。scanf函数与printf函数相对,前者是从标准输入设备输入数值,后者是从标准输出设备输出数值。
返回值:成功返回输入的字符个数,否则遇到结束符返回EOF,出错返回0。

#include <stdio.h>
void main( void )
{int i;char ch;float f;printf("Please input an integer:\n");scanf("%d",&i);getchar();printf("Please input a character:\n");scanf("%c",&ch);getchar();printf("Please input an float:\n");scanf("%f",&f);getchar();printf("These values are:%d,%c,%f",i,ch,f);
}

注意:scanf函数与fscanf函数类似,但只能从标准输入设备文件读取数值,而不能像fscanf函数一样从一般用户自定义文件中读取数值。scanf函数常用作程序设计中数据的输入函数。

1.4.10 向字符串写入格式化数据函数sprintf

函数原型:int sprintf(char string, char farmat [,argument,...]);
函数功能:将格式化的数据存储到以string为首地址的缓冲区中。参数argument要被转化为farmat规定的格式,并按照这个规定的格式向字符串数组写入数据。这里应该注意,sprintf函数与printf函数和fprint函数不同,前者是向缓冲区(即数组)写入格式化数据,后者是向标准输出文件(stdout)和用户自定义文件输出格式化数据。
返回值:返回存储在string中数据的字节数。

#include <stdio.h>
#include <math.h>
int main(void)
{char str[80];sprintf(str, "An approximation of Pi is %f\n", M_PI);puts(str);return 0;
}

注意puts函数的作用是把str指定的字符串输出到标准输出设备,并且将字符串结束标志\0转换为回车换行符。

1.4.11 从缓冲区中读格式化字符串函数sscanf

函数原型:int sscanf(char string, char format[,argument,...]);
函数功能:将string指定的数据读到argument所指定的位置。其中,参数argument是与format格式要求相符合的变量指针。也就是说,如果format指定的格式为%d,则argument就必须是整型变量的指针。这里应该注意,sscanf函数与scanf函数和fscanf函数不同,前者是从指定的缓冲区读格式化数据到新的缓冲区中,而后者是从标准输入文件(stdin)和用户自定义文件中读取格式化数据到缓冲区中。
返回值:成功返回已分配空间的数量,返回0表示没用空间分配,返回EOF表示出错。

#include <stdio.h>
void main( void )
{char  str[] = "1 2 3...";char  s[81];char  c;int   i;float fp;/* 从缓冲区str中读取数据 */sscanf( str, "%s", s );sscanf( str, "%c", &c );sscanf( str, "%d", &i );sscanf( str, "%f", &fp );/* 输出已读取的数据 */printf( "String    = %s\n", s );printf( "Character = %c\n", c );printf( "Integer:  = %d\n", i );printf( "Real:     = %f\n", fp );
}

1.4.12 把字符退回到输入流函数ungetc

函数原型:int ungetc(char c, FILE *fp);
函数功能:把字符c退回到fp所指向的文件流中,并清除文件的结束标志。fp所指向的文件既可以是用户自定义的文件,又可以是系统定义的标准文件。
返回值:成功返回字符c,否则返回EOF。

#include <stdio.h>
#include <ctype.h>
int main( void )
{int i=0;char ch;puts("Input an integer followed by a char:");/* 读取字符直到输入非数字或EOF */while((ch = getchar()) != EOF && isdigit(ch))i = 10 * i + ch - 48; /* 将ASCII码转换为整数值*//* 如果输入非数字,将其退回输入流 */if (ch != EOF)ungetc(ch, stdin);printf("i = %d, next char in buffer = %c\n", i, getchar());return 0;
}

注意:所谓将结尾的非数字字符退回到标准输入文件,就是说将数字字符串后面的那个非数字字符退回到标准输入文件中去。例如:输入的字符串为"123abc",那么退回的字符就是a。这样,程序将前面的字符串"123"转换为整型数123,并存入变量i中。a作为数字字符串输入的结束标志(因为 a是继数字字符之后的第一个非数字字符),被退回到标准输入文件(stdin)。于是,再调用getchar函数读取的字符就应该是刚刚退回到标准输入文件中的字符a。因此,本段例程的执行结果为:
Input an integer followed by a char:
123abc
i = 123, next char in buffer = a
即:输入的字符串中123 为整型数,接下来的字符为a。

1.5 输出函数

1.5.1 格式化输出函数fprintf

函数原型:int fprintf(FILE fp, char format[, argument,...]);
函数功能:把argument的值以format所指定的格式输出到fp指向的文件中。这个函数理解起来和printf类似,在一般的使用中,第二个参数可以是一个字符串的头指针,也可以就是一个字符串。例如:fprintf(fp, “Cannot open this file!!”),意思就是把字符串Cannot open this file!!输出到文件fp中去。该函数一般用作终端的出错提示或是在磁盘中生成错误报告。
返回值:如果正确返回实际输出字符数,若错误则返回一个负数。

#include <stdio.h>
int main(void)
{FILE *fp;/*以只读方式打开名为test.txt的文件*/if ((fp = fopen("\\test.txt", "rt"))  == NULL){fprintf(stderr, "Cannot open this file!!\n");return 1;    /*若该文件不能打开,在屏幕上显示出错提示*/}/*若该文件能够打开,在屏幕上显示正确提示*/fprintf(stderr,"Have open this file!!\n");return 0;
}

注意:该函数中第一个参数是stderr,这是C语言中标准出错输出指针,它指向标准的出错输出文件,也就是显示器。因为,在操作系统中,I/O设备都是用文件进行管理的,因此设备都配有相应的控制文件。在C语言中,有三个文件与终端相联系,因此系统定义了三个文件指针。

设备文件文件指针
标准输入stdin
标准输出stdout
标准出错输出stderr

用fprintf函数在磁盘中生成错误报告。

#include <stdio.h>
int main(void)
{FILE *fp1,*fp2;
/*以只读方式打开名为test.txt的文件*/if ((fp1 = fopen("text.txt", "rt")) == NULL){/*若文件打不开,则生成错误报告*/fp2=fopen("report.txt","w");fprintf(fp2, "Cannot open this file!!\n");return 1;}return 0;
}

注意:这里函数fprintf的第一个参数为文件指针,是用户自定义的,与上一例的系统定义的文件指针stderr不同。fprintf函数与printf函数的使用类似,其实printf函数是fprintf函数的一个特例,printf函数只能向标准输出文件(显示器)输出数据,而fprintf函数也可以向一般用户定义的文件输出数据。

1.5.2 向流中输出字符函数fputc

函数原型:int fputc(char ch, FILE *fp);
函数功能:将字符ch输出到fp指向的文件中。该函数与前边提到的fgetc是相对的,第一个参数ch是字符型变量,函数将该变量中的字符输出到fp指向的文件中。
返回值:成功返回该字符,否则返回非0。

#include <stdio.h>
int main(void)
{/*初始化字符数组str */char str[] = "This is a test";int i = 0;/*将数组中的字符循环输出至屏幕*/while (str[i]){fputc(str[i], stdout);i++;}return 0;
}

注意两点:

  • 该循环以\0作为结束标志,即循环碰到\0时结束。
  • 函数fputc的第二个参数是stdout,它代表标准输出文件指针,这样就是在屏幕上显示该字串。

1.5.3 向流中输出字符串函数fputs

函数原型:int fputs(char string, FILE fp);
函数功能:将string所指的字符串输出到fp指向的文件中。该函数与fgets相对,第一个参数为字符串指针。与fgets函数不同的是,fputs函数没有字符串长度的限制,只是将string指向的字符串输出到文件中。
返回值:成功返回0,否则返回非0。

#include <stdio.h>
int main(void)
{FILE *fp;char str[]="This is a test!";/*以写的方式打开名为test.txt的文件*/fp=fopen("test.txt","w");/*将字符串写入文件*/fputs(str,fp);fclose(fp);return 0;
}

1.5.4 格式化输入函数fscanf

函数原型:int fscanf(FILE fp, char format[,argument...]);
函数功能:从fp所指向的文件中按format给定的格式读取数据到argument所指向的内存单元。其中argument是指针,指针类型要与输入的格式format相一致。例如:fscanf(stdin, "%d", &i); &i是整型的指针,输入的格式format也要为整型,即"%d"。
返回值:返回已输入的数据个数。若错误或文件结束返回EOF。

#include <stdlib.h>
#include <stdio.h>
int main(void)
{char ch;printf("Please input an character ");/* 从标准输入文件中读取一个字符,并送至ch */if (fscanf(stdin, "%c", &ch))printf("The character  was: %c\n",ch);else{/*出错提示*/fprintf(stderr, "Error reading an character from stdin!!\n");exit(1);}return 0;
}

这里应该注意两点:

  • fscanf函数的第一个参数不是用户定义的文件指针,而是系统定义的标准输入文件指针stdin。但用法与用户定义的文件指针类似。
  • &ch是指向字符型数据的指针,因此,输入的格式format也要为字符型"%c",它们必须保持一致。

该函数的使用与scanf类似。其实,scanf函数是fscanf函数的一个特例,它只能从标准输入文件(键盘终端)中输入数据。而fscanf函数则也可以从一般用户定义的文件中输入数据。

1.5.5 打印系统错误信息函数perror

函数原型:void perror(char *string);
函数功能:将错误信息输出到标准出错输出stderr。该函数的参数是字符串指针,指向错误信息字符串。也可以就是一个字符串,直接在参数中输入要显示的错误信息。但要注意,完整的错误信息不仅包括用户在参数中自己定义的字符串,还包括一个冒号,系统报错信息,和一个换行符。该函数主要用作向终端进行错误提示。
返回值:无。

#include <stdio.h>
int main(void)
{FILE *fp;/*企图以读的方式打开文件test.txt*/fp = fopen("test.txt", "r");if (fp==NULL)/*该文件不存在,在终端显示错误信息*/perror("Unable to open file for reading");return 0;
}运行结果格式如下:
Unable to open file for reading: No such file or directory

注意:完整的错误信息包括:用户自定义字符串冒号,系统报错信息,换行符。

1.5.6 产生格式化输出的函数printf

函数原型:int printf( const char *format [, argument]... );
函数功能:按format指向的格式字符串所规定的格式,将输出表列argument的值输出到标准输出设备。该函数与fprintf类似,但只能将argument的值输出到标准输出设备stdout,即显示器屏幕,而不能输出到用户自定义的文件中。
返回值:输出字符的个数,若出错则返回一个负数。

#include <stdio.h>
#include <string.h>
int main(void)
{int a=1;char ch='r';char str[]="This is a test!";printf("Output a string.\n");printf("%s",str);printf("The integer is %d\n",a);printf("The character is %c\n",ch);return 0;
}

1.5.7 向指定流中输出字符函数putc

函数原型:int putc(int ch, FILE *fp);
函数功能:向指定的文件输出一个字符。该函数有两个参数,ch是用户指定的字符,fp是文件指针。函数将字符ch输出到fp指定的文件中。
返回值:返回输出的字符ch,若出错则返回EOF。

#include <stdio.h>
int main(void)
{char str[] = "Hello world!";int i = 0;while (str[i]){putc(str[i], stdout);i++;}return 0;
}
include <stdio.h>
int main(void)
{FILE *fp;int i = 0;char str[]="This is a test!";fp=fopen("test.txt","w");while (str[i]){putc(str[i], fp);i++;}fclose(fp);return 0;
}

注意:该函数既可以向标准输出文件输出字符,又可以向用户自定义文件输出字符。而且,每当向文件输出一个字符时,文件指针就会自动向后移一个字节。

1.5.8 向标准输出文件上输出字符putchar

函数原型:int putchar(char ch);
函数功能:将字符串ch输出到标准输出文件stdout上。也就是说将字符串ch输出到显示器屏幕上。
返回值:返回输出的字符ch,若出错,则返回EOF。

include <stdio.h>
int main()
{char str[]="This is a test!\n";int i=0;while(str[i]){putchar(str[i]);i++;}
}

注意:该函数与putc函数不同,它只能向标准输出文件,也就是终端屏幕上输出字符。而putc函数既可以向标准输出文件上输出字符,又可以向一般用户自定义文件上输出字符。

1.5.9 将字符串输出到终端函数puts

函数原型:int puts(char *string);
函数功能:将string指向的字符串输出到标准输出设备(stdout),并将\0转换为回车换行符\n。在C语言中,字符串以’\0’结尾。该函数不仅可以将字符串输出到标准输出设备,而且要将字符串的结束标志转换为回车换行。
返回值:成功则返回换行符,若失败则返回EOF

#include <stdio.h>
int main(void)
{char string[] = "This is a test!\n";puts(string);return 0;
}

注意:该函数将字符串的结尾标志\0转换为回车换行符\n

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/858085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

树状数组维护区间种类数

[SDOI2009] HH的项链 题目描述 HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运&#xff0c;所以每次散步完后&#xff0c;他都会随意取出一段贝壳&#xff0c;思考它们所表达的含义。HH 不断地收集新的贝壳&#xff0c;因此&#xff0c;他的项链变得越来…

八爪鱼现金流-027,以后别再做软件开发了,累了,要有自己的作品

别做软件开发了&#xff0c;太恶心了。 裁员好几波人&#xff0c;他们的项目就给到剩下的人身上了。 然后工作量翻倍&#xff0c;主要是遗留的项目也一堆bug.人员流动性太大。 项目的产品也换人了。开发也换了。没有人熟悉这个项目了。 现状就是&#xff0c;先看页面&#xff…

什么是熵、熵增是什么?

目录 一、熵的定义1. 热力学中的熵2. 信息论中的熵 二、熵增三、生活中的熵增示例四、总结 一、熵的定义 1. 热力学中的熵 熵&#xff08;entropy&#xff09;&#xff0c;在热力学中&#xff0c;熵是描述系统混乱程度或无序程度的物理量。它反映了系统在微观上可访问的状态数…

简易智能家居系统

文章目录 摘要一、系统设计要求及总体设计方案1.1 设计要求1.2 总体设计方案 二、终端结点的设计及实现2.1单片机最小系统2.2 LED灯的控制与工作状态的显示2.2.1 硬件设计2.2.2 软件设计 2.3 温度的测量与显示2.4 火灾的监测与报警2.5 串口的显示与控制 三、网络传输与控制3.1 …

拦截器Interceptor

概念&#xff1a;是一种动态拦截方法调用的机制&#xff0c;类似于过滤器。Spring框架中提供的&#xff0c;用来动态拦截方法的执行。 作用&#xff1a;拦截请求&#xff0c;在指定的方法调用前后&#xff0c;根据业务需要执行预先设定的代码。

vue3中的readonly

<template><div>{{ sum }}{{ person }}<button click"ssum">修改sum</button><button click"sperson">修改name</button><button click"spage">修改age</button><button click"carcar1…

【杂记-浅谈OSPF协议中的邻居关系与邻接关系】

OSPF协议中的邻居关系与邻接关系 1、邻居关系2、邻接关系3、DR-other之间的邻居关系 在OSPF协议中&#xff0c;Neighbor relationship 邻居关系和Adjacency 邻接关系是两个核心概念&#xff0c;它们在路由器之间建立正确的路由信息传递机制方面起着关键作用。 1、邻居关系 邻…

已解决javax.management.BadAttributeValueExpException异常的正确解决方法,亲测有效!!!

已解决javax.management.BadAttributeValueExpException异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 分析错误日志 检查属性值合法性 确认属性类型匹配 优化代码逻辑 增…

js函数内 this 指向的不同场景

在 JavaScript 中&#xff0c;函数内部的 this 关键字是一个特殊的对象&#xff0c;它的值取决于函数被调用的方式。this 可以指向不同的对象&#xff0c;因此在不同的场景中它会有不同的含义。下面是一些常见的场景以及 this 的指向&#xff1a; 全局作用域&#xff1a;当函数…

后端数据null前端统一显示成空

handleNullValues方法在封装请求接口返回数据时统一处理 // null 转 function handleNullValues(data) {// 使用递归处理多层嵌套的对象或数组function processItem(item) {if (Array.isArray(item)) {return item.map(processItem);} else if (typeof item object &&…

Linux内存从0到1学习笔记(8.17 SMMU Fault调试方法)

写在前面 通过前面的介绍,我们知道了SMMU实际上是一个针对外设的MMU。它作为一个硬件IP被设备执行DMA操作时使用。 再来简单回顾下SMMU的工作流程: 外设 ---> DMA操作 ---> SMMU ---> Memory 也就是说,通常情况下驱动程序会先分配DMA Buffer ---> 然后执行S…

重庆思庄技术分享——启动Oracle下最小追踪日志

启动Oracle下最小追踪日志 11g默认是关闭的&#xff1a; SQL> select supplemental_log_data_min from v$database; SUPPLEME -------- NO 打开方式&#xff1a; SQL> alter database add supplemental log data; Database altered. SQL> select supplemental_log_d…

学会python——对目录的操作(python实例十)

目录 1、认识Python 2、环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3、遍历当前目录 3.1 代码构思 3.2 代码示例 3.3 运行结果 4、删除目录中的文件 4.1 代码构思 4.2 代码示例 4.3 运行结果 5、总计 1、认识Python Python 是一个高层次的结合了解释性…

C Tips: 举例说明在 Visual C++ 中忽略 C4996 编译警告的几种方法

C4996 编译警告非常常见&#xff0c;经常发生在程序调用了类似于strcpy这样的不够安全的函数时。例如以下代码在 Visual C 的默认工程设置中会引起 C4996 编译警告&#xff1a; void foo() {char filename[MAX_PATH];strcpy(filename, "D:\\Pub\\Test\\1.dat"); }编…

AI视频教程下载-与ChatGPT结合的UX用户体验/UI用户界面设计策略

Revolutionize UX_UI_ AI-Design Strategies with ChatGPT 提升你的设计工具包&#xff1a;使用ChatGPT、Figma和Miro的AI驱动UX/UI策略 50个创新UX提示 了解人工智能的基础知识。介绍ChatGPT及其底层技术。区分不同AI模型及其在设计中的应用。将AI工具融入设计工作流程的策略…

高纯PFA容量瓶PFA试剂瓶在半导体材料的应用

在半导体生产过程中&#xff0c;为避免金属污染对硅器件性能造成不利影响&#xff0c;碳化硅产业链不同阶段产品&#xff08;如衬底、外延、芯片、器件&#xff09;表面的痕量杂质元素浓度表征至关重要。 在实验人员使用质谱法高精度检测第三代半导体碳化硅材料的痕量杂质浓度…

高级IO操作

高级I/O操作与非阻塞I/O 在操作系统中&#xff0c;I/O&#xff08;输入/输出&#xff09;操作是所有实现的基础。本文将探讨阻塞I/O与非阻塞I/O的区别&#xff0c;以及如何使用有限状态机来实现非阻塞I/O&#xff0c;并介绍数据中继的概念。 阻塞I/O与非阻塞I/O 阻塞I/O 阻…

数据结构历年考研真题对应知识点(栈和队列的应用)

目录 3.3栈和队列的应用 3.3.2栈在表达式求值中的应用 【中缀表达式转后缀表达式的过程(2012、2014)】 【栈的深度分析(2009、2012)】 【用栈实现表达式求值的分析(2018)】 3.3.3栈在递归中的应用 【栈在函数调用中的作用和工作原理(2015、2017)】 3.3.5队列在计算机系…

docker搭建mongo副本集

1、mongo集群分类 MongoDB集群有4种类型&#xff0c;分别是主从复制、副本集、分片集群和混合集群。 MongoDB的主从复制是指在一个MongoDB集群中&#xff0c;一个节点&#xff08;主节点&#xff09;将数据写入并同步到其他节点&#xff08;从节点&#xff09;。主从复制提供…

L56---226.翻转二叉树(广搜)---Java版

1.题目描述 2.思路和知识点 &#xff08;1&#xff09;按照每层来划分&#xff0c; 第一层是2^0&#xff08; 1&#xff09; 第二层是2^1&#xff08;2&#xff0c;3&#xff09; 第三层是2^2 &#xff08;4&#xff0c;5&#xff0c;6&#xff0c;7&#xff09; 第n层是2^(n-…