目录
目录
目录
前言
1.C 标准库 - <stdio.h>
简介
1.1 printf();
1.2 scanf();
1.3 getchar();
1.4 putchar();
1.5 gets();
1.6 puts();
1.7fscanf();
1.8 fprintf();
1.9 fgetc();
1.10 fgets();
1.11 fputs();
1.12 fclose();
1.13 clearerr();
1.14 feof();
1.15 ferror();
1.16 fflush();
1.17 fgetpos();
1.18 fopen();
1.19 fread();
1.20 freopen();
1.21 fseek();
1.22 fsetpos();
1.23 ftell();
1.24 fwrite();
1.25 remove();
1.26 rename();
1.27 rewind();
1.28 setbuf();
1.29 setvbuf();
1.30 tmpfile();
1.31 tmpnam();
2. C 标准库 - <stdlib.h>
2.1 callo();
2.2 free();
2.3 mallo();
2.4 realloc();
2.5 rand();
2.6 abort();
2.7 exit();
2.8 getenv();
2.9 putenv();
2.10 labs();
2.11 atof();
2.12 atof();
2.13 atoi();
2.14 atol();
2.15 exvt();
2.16 fcvt();
3.C 标准库 - <math.h>
简介
3.1 abs();
3.2 sqrt();
3.3 pow();
3.4 fabs();
3.5 acos();
3.6 asin();
3.7 atan();
3.8 atan2();
3.9 ceil();
3.10 cos();
3.11 cosh();
3.12 exp();
3.13 floor();
3.14 fmod();
3.15 frexp();
3.16 hypot();
3.17 ldexp();
3.18 log();
3.19 log10();
3.20 modf();
3.21 pow10();
3.22 sin();
3.23 sinh();
3.24 tan();
3.25 tanh();
4.C 标准库 - <string.h>
简介
4.1 bcmp();
4.2 bcopy();
4.3 bzeor();
4.4 memccpy();
4.5 memchr();
4.6 memcmp();
4.7 memcpy();
4.8 memicmp();
4.9 memmove();
4.10 memset();
4.11 movmem();
4.12 setmem();
4.13 stpcpy();
4.14 strcat();
4.15 strchr();
4.16 strcmp();
4.17 strcmpi();
4.18 strcpy();
4.19 strcspn();
4.20 strdup();
4.21 stricmp();
4.22 strlen();
4.23 strlwr();
4.24 strncat();
4.25 strncmp();
4.26 strncmpi();
4.27 strncpy();
4.28 strnicmp();
4.29 strpbrk();
4.30 strrev();
4.31 strset();
4.32 strstr();
4.33 strtok();
4.34strupr();
5.C 系统函数库 -<windows.h>
简介
5.1 Sleep();
5.2 sytem("pause";);
5.3 sytem("cls");
5.4 FinWindow();
5.5 SendMessage();
5.6 WindowFromPoin();
5.7 GetCusorPos();
5.8 SetCursorPos();
5.9 ShowWindow();
6.C 标准库 -
6.1 isalnum() ;
6.2 isalpha() ;
6.3 iscntrl();
6.4 isdigit();
6.5 isgraph();
6.6 islower();
6.7 isprint();
6.8 ispunct();
6.9 isspace();
6.10 isupper();
6.11 isxdigit();
7.C 标准库 -
简介
库宏
7.1 extern int errno
7.2 #define EDOM some_value
7.3 #define ERANGE some_value
8. C 标准库 - <float.h>
简介
宏
8.1 FLT_ROUNDS
8.2 FLT_RADIX 2
8.3
FLT_MANT_DIG
DBL_MANT_DIG
LDBL_MANT_DIG
8.4
FLT_DIG 6
DBL_DIG 10
LDBL_DIG 10
8.5
FLT_MIN_EXP
DBL_MIN_EXP
LDBL_MIN_EXP
8.6
FLT_MIN_10_EXP -37
DBL_MIN_10_EXP -37
LDBL_MIN_10_EXP -37
8.7
FLT_MAX_EXP
DBL_MAX_EXP
LDBL_MAX_EXP
8.8
FLT_MAX_10_EXP +37
DBL_MAX_10_EXP +37
LDBL_MAX_10_EXP +37
8.9
FLT_MAX 1E+37
DBL_MAX 1E+37
LDBL_MAX 1E+37
8.10
FLT_EPSILON 1E-5
DBL_EPSILON 1E-9
LDBL_EPSILON 1E-9
8.11
FLT_MIN 1E-37
DBL_MIN 1E-37
LDBL_MIN 1E-37
实例
9. C 标准库 -
简介
库宏
9.1 CHAR_BIT
9.2 SCHAR_MIN
9.3 SCHAR_MAX
9.4 UCHAR_MAX
9.5 CHAR_MIN
9.6 CHAR_MAX
9.7 MB_LEN_MAX
9.8 SHRT_MIN
9.9 SHRT_MAX
9.10 USHRT_MAX
9.11 INT_MIN
9.12 INT_MAX
9.13 UINT_MAX
9.14 LONG_MIN
9.15 LONG_MAX
9.16 ULONG_MAX
10.C 标准库 -
描述
10.1 setlocale();
10.2 localeconv();
库宏
10.1.1 LC_ALL
10.12 LC._COLLATE
10.1.3 LC_CTYPE
10.1.4 LC_MONETARY
10.1.5 NUMERIC
10.1.6 LC_TIME
11.C标准库-
11.1 asctime();
11.2 cIock();
11.3 ctime();
11.4 difftime();
11.5 gmtime();
11.6 Iocaltime();
11.7 mktime();
11.8 strftime();
11.9 time();
宏
11.1.1 NULL
11.1.2 CLOCKS_PER_SEC
12.C标准库—
描述
12.1 longjmp();
13.C标准库-
描述
13.1 signal();
13.2 raise();
14.C图形库-
1.setbkcolor();
2.outtextx();
3.settextstyle();
4.line();
5.selinecolor();
6.putpixel();
7.retangle();
8.fillcircle();
9.cleardevice();
10.beginBatchdraw();
EndBatchDraw();
11.putimage();
12.getwidth();
getheight();
13.setfillcolor();
14.closegraph();
15.initgraph();
16.GetsytemMetrics();
17.GetSystemMetrics();
前言
作者:写C的初级码农
简介: 一名正在努力学习的大一学生
给读者的话 :
当我正值青春的年纪里,很高兴能结识了一群花样年华的你们。当幸福像花儿一样盛开,请允许我记住在花季里始终如一关注我的你。
一路走过,一路记忆。每一次转身,都是一次与回忆的碰面。看看来时路,才发现,你们不曾离去。都在路上,一直陪伴在我左右,和我一起静候着下一个春暖花开。
1.C 标准库 - <stdio.h>
简介
stdio .h 头文件定义了三个变量类型、一些宏和各种函数来执行输入和输出。
1.1 printf();
函数简介——
printf() 是 C 语言标准库函数,用于将格式化后的字符串输出到标准输出。标准输出,即标准输出文件,对应终端的屏幕。printf() 申明于头文件 stdio.h。
函数原型——
int printf ( const char * format, ... );
函数调用格式—
printf("<格式化字符串>", <参量表>);
返回值类型—
正确返回输出的字符总数,错误返回负值。与此同时,输入输出流错误标志将被置值,可由指示器函数 ferror(FILE *stream) 来检查输入输出流的错误标志,如果 ferror() 返回一个非零值,表示出错。
测试用例
#include <stdio.h>
int main()
{
char ch = 'A';
char str[20] = "www.runoob.com";
float flt = 10.234;
int no = 150;
double dbl = 20.123456;
printf("字符为 %c \n", ch);
printf("字符串为 %s \n" , str);
printf("浮点数为 %f \n", flt);
printf("整数为 %d\n" , no);
printf("双精度值为 %lf \n", dbl);
printf("八进制值为 %o \n", no);
printf("十六进制值为 %x \n", no);
return 0;
}
输出样例为:
字符为 A
字符串为 www.runoob.com
浮点数为 10.234000
整数为 150
双精度值为 20.123456
八进制值为 226
十六进制值为 96
转义字符
- %d 十进制有符号整数
- %u 十进制无符号整数
- %f 浮点数
- %s 字符串
- %c 单个字符
- %p 指针的值
- %e 指数形式的浮点数
- %x, %X 无符号以十六进制表示的整数
- %o 无符号以八进制表示的整数
- %g 把输出的值按照 %e 或者 %f 类型中输出长度较小的方式输出
- %p 输出地址符
- %lu 32位无符号整数
- %llu 64位无符号整数
1.2 scanf();
函数简介—
scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息。
可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。
如果需要使用scanf()函数则需要包含头文件 <stdio.h>
函数原型—
int scanf(const char *format, ...)
函数调用格式—
scanf("输入控制符", 输入参数);
返回值类型—
成功则该函数返回成功匹配和赋值的个数。
如果到达文件末尾或发生读错误,则返回 EOF。
测试样例—
#include<stdio.h>
int main(void)
{
int a,b,c;
printf("请输入三个数字:");
scanf("%d%d%d",&a,&b,&c);
printf("%d,%d,%d\n",a,b,c);
return 0;
}
交互界面—
请输入三个数字:1, 2, 3
1, 2, 3
注意事项—
注意:输入时 , 前一定要紧跟在数字后面,数字与 , 之间不能有空格。
在用 %c 输入时,空格和"转义字符"均作为有效字符。
解析说明 —
- 1、&a、&b、&c 中的 & 是地址运算符,分别获得这三个变量的内存地址。
- 2、%d%d%d 是按十进值格式输入三个数值。输入时,在两个数据之间可以用一个或多个空格、tab 键、回车键分隔。
测试样例二—
#include<stdio.h>
int main(void)
{
char a,b,c;
printf("请输入三个字符:");
scanf("%c%c%c",&a,&b,&c);
printf("%c,%c,%c\n", a,b,c);
return 0;
}
输出结果
$ ./a.out
请输入三个字符:run
r,u,n
$ ./a.out
请输入三个字符:r u n
r, ,u
输入字符串
#include<stdio.h>
#include<stdlib.h>
int main(){
system("color F4");
int i=0;
char c;
char s[5];
for(i=0;i<5;i++){
scanf("%c",&s[i]);
c = s[i];
printf("%c %c\n",s[i],c);
}
return 0;
}
输出结果 —
scanf 类型说明符—:
%a、%A | 读入一个浮点值(仅 C99 有效)。 | float * |
%c | 单个字符:读取下一个字符。如果指定了一个不为 1 的宽度 width,函数会读取 width 个字符,并通过参数传递,把它们存储在数组中连续位置。在末尾不会追加空字符。 | char * |
%d | 十进制整数:数字前面的 + 或 - 号是可选的。 | int * |
%e、%E、%f、%F、%g、%G | 浮点数:包含了一个小数点、一个可选的前置符号 + 或 -、一个可选的后置字符 e 或 E,以及一个十进制数字。两个有效的实例 -732.103 和 7.12e4 | float * |
%i | 读入十进制,八进制,十六进制整数 。 | int * |
%o | 八进制整数。 | int * |
%s | 字符串。这将读取连续字符,直到遇到一个空格字符(空格字符可以是空白、换行和制表符)。 | char * |
%u | 无符号的十进制整数。 | unsigned int * |
%x、%X | 十六进制整数。 | int * |
%p | 读入一个指针 。 | |
%[] | 扫描字符集合 。 | |
%% | 读 % 符号。 |
1.3 getchar();
函数简介—
getchar函数有一个int或者char型的返回值,当程序调用getchar时,程序就等着用户键盘按键。
用户输入的字符被存放在键盘缓冲区中。直到用户按回车为止(回车字符也放在缓冲区中),当用户键入回车之后,getchar才开始从缓冲区中读入字符,例如:用户按下键盘的a键,那么getchar函数就返回字符a;
函数原型—
int getchar(void)
调用格式 —
getchar();
返回值类型—
该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。
测试样例—
#include <stdio.h>
int main ()
{
char c;
printf("请输入字符:");
c = getchar();
printf("输入的字符:");
putchar(c);
return(0);
}
输出结果—
请输入字符:a
输入的字符:a
getchar()的额外作用:清除\n
#include <stdio.h>
int main(){
char a[100];
printf("请输入: ");
scanf("%s",&a);
printf("字符的值为: ");
printf("请输入: ");
printf("%c",getchar());
printf("%c",getchar());
printf("%c",getchar());
return 0;
}
编译运行:
请输入:123
字符的值为:123
请输入:
12
12
在这里,第一个 getchar() 读取了上次 scanf() 的回车,体现在第二个“请输入”后出现了换行,第二、三个 getchar分别 读取 1 和 2,因此 3 没有读取出来。
要避免这种情况,就要在 getchar 前清空缓存区中的回车,可以用 C 语言的基本语法:
char c_tmp; while ((c_tmp!='\n')&&c_tmp!='EOF');
代码优化为—
#include <stdio.h>
int main(){
char a[100];
printf("请输入: ");
scanf("%s",&a);
printf("字符的值为: ");
//fflush(stdin);
char c_tmp;
while ((c_tmp!='\n')&&c_tmp!='EOF');
printf("请输入: ");
printf("%c",getchar());
printf("%c",getchar());
printf("%c",getchar());
return 0;
}
输出—:
请输入:123 字符的值为:123 请输入:123 123
1.4 putchar();
函数简介——
putchar函数是字符输出函数,是put character的缩写,它的作用是在显示器上输出单个字符。
函数原型——:
int putchar(int char)
调用格式——
putchar(字符变量);
返回值类型——
该函数以无符号 char 强制转换为 int 的形式返回写入的字符,如果发生错误则返回 EOF。
测试样例——
#include <stdio.h>
int main ()
{
char ch;
for(ch = 'A' ; ch <= 'Z' ; ch++) {
putchar(ch);
}
return(0);
}
输出样例——
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1.5 gets();
函数简介——
C 库函数 char *gets(char *str) 从标准输入 stdin 读取一行,并把它存储在 str 所指向的字符串中。当读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
函数原型——
char *gets(char *str)
调用格式——
gets(字符变量);
返回值类型——
如果成功,该函数返回 str。如果发生错误或者到达文件末尾时还未读取任何字符,则返回 NULL。
测试样例——
#include <stdio.h>
int main()
{
char str[50];
printf("请输入一个字符串:");
gets(str);
printf("您输入的字符串是:%s", str);
return(0);
}
输出样例——
请输入一个字符串:runoob
您输入的字符串是:runoob
gets的注意事项 ——
关于使用 gets() 函数需要注意:使用 gets() 时,系统会将最后“敲”的换行符从缓冲区中取出来,然后丢弃,所以缓冲区中不会遗留换行符。这就意味着,如果前面使用过 gets(),而后面又要从键盘给字符变量赋值的话就不需要吸收回车清空缓冲区了,因为缓冲区的回车已经被 gets() 取出来扔掉了。下面写一个程序验证一下:
# include <stdio.h>
int main(void)
{
char str[30];
char ch;
printf("请输入字符串:");
gets(str);
printf("%s\n", str);
scanf("%c", &ch);
printf("ch = %c\n", ch);
return 0;
}
输出结果是——:
请输入字符串:i love you
i love you
Y
ch = Y
我们看到,没有清空缓冲区照样可以输入'Y',因为 gets() 已经将缓冲区中的回车取出来丢掉了。如果前面使用的不是 gets() 而是 scanf,那么通过键盘给 ch 赋值前就必须先使用 getchar() 清空缓冲区。
1.6 puts();
函数简介——:
puts()函数用来向标准输出设备(屏幕)输出字符串并换行
函数原型——
int puts(const char *st
返回值类型——
如果成功,该函数返回一个非负值为字符串长度(包括末尾的 \0),如果发生错误则返回 EOF。
测试样例——
#include <stdio.h>
#include <string.h>
int main()
{
char str1[15];
char str2[15];
strcpy(str1, "RUNOOB1");
strcpy(str2, "RUNOOB2");
puts(str1);
puts(str2);
return(0);
}
输出样例——
RUNOOB1
RUNOOB2
注意事项——
(1) puts()函数只能输出字符串, 不能输出数值或进行格式变换。
(2)可以将字符串直接写入puts()函数中。如:\n\nputs(\"Hello, world!");
(3) puts 和 printf的用法一样,puts()函数的作用与语句“printf("%s",s);的作用相同。注意:puts在输出字 符串后会自动输出一个回车符。
1.7fscanf();
函数简介——
C 库函数 int fscanf(FILE *stream, const char *format, ...) 从流 stream 读取格式化输入。
函数原型——
int fscanf(FILE *stream, const char *format, ...)
返回值类型——
如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。
fscanf转义字符——
c | 单个字符:读取下一个字符。如果指定了一个不为 1 的宽度 width,函数会读取 width 个字符,并通过参数传递,把它们存储在数组中连续位置。在末尾不会追加空字符。 | char * |
d | 十进制整数:数字前面的 + 或 - 号是可选的。 | int * |
e,E,f,g,G | 浮点数:包含了一个小数点、一个可选的前置符号 + 或 -、一个可选的后置字符 e 或 E,以及一个十进制数字。两个有效的实例 -732.103 和 7.12e4 | float * |
o | 八进制整数。 | int * |
s | 字符串。这将读取连续字符,直到遇到一个空格字符(空格字符可以是空白、换行和制表符)。 | char * |
u | 无符号的十进制整数。 | unsigned int * |
x,X | 十六进制整数。 | int * |
附加参数 ——
- -- 根据不同的 format 字符串,函数可能需要一系列的附加参数,每个参数包含了一个要被插入的值,替换了 format 参数中指定的每个 % 标签。参数的个数应与 % 标签的个数相同。
测试样例——
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str1[10], str2[10], str3[10];
int year;
FILE * fp;
fp = fopen ("file.txt", "w+");
fputs("We are in 2014", fp);
rewind(fp);
fscanf(fp, "%s %s %s %d", str1, str2, str3, &year);
printf("Read String1 |%s|\n", str1 );
printf("Read String2 |%s|\n", str2 );
printf("Read String3 |%s|\n", str3 );
printf("Read Integer |%d|\n", year );
fclose(fp);
return(0);
}
输出结果——
Read String1 |We|
Read String2 |are|
Read String3 |in|
Read Integer |2014|
1.8 fprintf();
函数简介——
C 库函数 int fprintf(FILE *stream, const char *format, ...) 发送格式化输出到流 stream 中。
函数原型——
int fprintf(FILE *stream, const char *format, ...)
返回值类型——
如果成功,则返回写入的字符总数,否则返回一个负数。
格式转换符——
specifier(说明符) | 输出 |
---|---|
c | 字符 |
d 或 i | 有符号十进制整数 |
e | 使用 e 字符的科学科学记数法(尾数和指数) |
E | 使用 E 字符的科学科学记数法(尾数和指数) |
f | 十进制浮点数 |
g | 自动选择 %e 或 %f 中合适的表示法 |
G | 自动选择 %E 或 %f 中合适的表示法 |
o | 有符号八进制 |
s | 字符的字符串 |
u | 无符号十进制整数 |
x | 无符号十六进制整数 |
X | 无符号十六进制整数(大写字母) |
p | 指针地址 |
n | 无输出 |
% | 字符 |
lags(标识) | 描述 |
---|---|
- | 在给定的字段宽度内左对齐,默认是右对齐(参见 width 子说明符)。 |
+ | 强制在结果之前显示加号或减号(+ 或 -),即正数前面会显示 + 号。默认情况下,只有负数前面会显示一个 - 号。 |
(space) | 如果没有写入任何符号,则在该值前面插入一个空格。 |
# | 与 o、x 或 X 说明符一起使用时,非零值前面会分别显示 0、0x 或 0X。 与 e、E 和 f 一起使用时,会强制输出包含一个小数点,即使后边没有数字时也会显示小数点。默认情况下,如果后边没有数字时候,不会显示显示小数点。 与 g 或 G 一起使用时,结果与使用 e 或 E 时相同,但是尾部的零不会被移除。 |
0 | 在指定填充 padding 的数字左边放置零(0),而不是空格(参见 width 子说明符)。 |
width(宽度) | 描述 |
---|---|
(number) | 要输出的字符的最小数目。如果输出的值短于该数,结果会用空格填充。如果输出的值长于该数,结果不会被截断。 |
* | 宽度在 format 字符串中未指定,但是会作为附加整数值参数放置于要被格式化的参数之前。 |
.precision(精度) | 描述 |
---|---|
.number | 对于整数说明符(d、i、o、u、x、X):precision 指定了要写入的数字的最小位数。如果写入的值短于该数,结果会用前导零来填充。如果写入的值长于该数,结果不会被截断。精度为 0 意味着不写入任何字符。 对于 e、E 和 f 说明符:要在小数点后输出的小数位数。 对于 g 和 G 说明符:要输出的最大有效位数。 对于 s: 要输出的最大字符数。默认情况下,所有字符都会被输出,直到遇到末尾的空字符。 对于 c 类型:没有任何影响。 当未指定任何精度时,默认为 1。如果指定时不带有一个显式值,则假定为 0。 |
.* | 精度在 format 字符串中未指定,但是会作为附加整数值参数放置于要被格式化的参数之前。 |
length(长度) | 描述 |
---|---|
h | 参数被解释为短整型或无符号短整型(仅适用于整数说明符:i、d、o、u、x 和 X)。 |
l | 参数被解释为长整型或无符号长整型,适用于整数说明符(i、d、o、u、x 和 X)及说明符 c(表示一个宽字符)和 s(表示宽字符字符串)。 |
L | 参数被解释为长双精度型(仅适用于浮点数说明符:e、E、f、g 和 G)。 |
这一段可以参考菜鸟教程—fprintf详解
测试用例——
#include<stdio.h>
#define N 2
struct stu{
char name[10];
int num;
int age;
float score;
} boya[N], boyb[N], *pa, *pb;
int main(){
FILE *fp;
int i;
pa=boya;
pb=boyb;
if( (fp=fopen("D:\\demo.txt","wt+")) == NULL ){
puts("Fail to open file!");
exit(0);
}
//从键盘读入数据,保存到boya
printf("Input data:\n");
for(i=0; i<N; i++,pa++){
scanf("%s %d %d %f", pa->name, &pa->num, &pa->age, &pa->score);
}
pa = boya;
//将boya中的数据写入到文件
for(i=0; i<N; i++,pa++){
fprintf(fp,"%s %d %d %f\n", pa->name, pa->num, pa->age, pa->score);
}
//重置文件指针
rewind(fp);
//从文件中读取数据,保存到boyb
for(i=0; i<N; i++,pb++){
fscanf(fp, "%s %d %d %f\n", pb->name, &pb->num, &pb->age, &pb->score);
}
pb=boyb;
//将boyb中的数据输出到显示器
for(i=0; i<N; i++,pb++){
printf("%s %d %d %f\n", pb->name, pb->num, pb->age, pb->score);
}
fclose(fp);
return 0;
}
输出结果——
Input data:
Tom 2 15 90.5
Li 1 14 99
Tom 2 15 90.500000
Li 1 14 99.000000
1.9 fgetc();
函数简介——
该函数包含在C语言中的stdio.h头文件中,主要功能是从流中读取一个字符,并增加文件指针的位置。
函数原型——
int fgetc(FILE *fp);
函数功能——
从流中读取字符,即从fp所指定的文件中取得下一个字符。这里需要注意,在每取完一个字符时fp会自动向下移动一个字节。这样编成时,程序员就不用再对fp控制了。这种功能在许多读写函数中都有体现。
测试样例——
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
int n = 0;
fp = fopen("file.txt","r");
if(fp == NULL)
{
perror("打开文件时发生错误");
return(-1);
}
do
{
c = fgetc(fp);
if( feof(fp) )
{
break ;
}
printf("%c", c);
}while(1);
fclose(fp);
return(0);
}
输出结果——
现在让我们假设有一个文本文件 file.txt,它的内容如下。文件将作为实例中的输入:
We are in 2014
让我们编译并运行上面的程序,这将产生以下结果:
We are in 2014
1.10 fgets();
函数简介——
fgets()函数的作用就是用来读取一行数据的。但要详细且专业的说的话,fgets()函数的作用可以这么解释:从第三个参数指定的流中读取最多第二个参数大小的字符到第一个参数指定的容器地址中。在这个过程中,在还没读取够第二个参数指定大小的字符前,读取到换行符'\\n'或者需要读取的流中已经没有数据了。则提前结束,并把已经读取到的字符存储进第一个参数指定的容器地址中。
函数原型 ——
char *fgets(char *str, int n, FILE *stream)
测试样例 ——
# include <stdio.h>
int main(void)
{
char str[30];
char ch;
printf("请输入字符串:");
fgets(str, 29, stdin);
printf("%s", str); //后面不要加'\n'
scanf("%c", &ch);
printf("ch = %c\n", ch);
return 0;
}
输出结果——
请输入字符串:i love you
i love you
Y
ch = Y
使用时的建议——
虽然用 gets() 时有空格也可以直接输入,但是 gets() 有一个非常大的缺陷,即它不检查预留存储区是否能够容纳实际输入的数据,换句话说,如果输入的字符数目大于数组的长度,gets 无法检测到这个问题,就会发生内存越界,所以编程时建议使用 fgets()。
fgets() 虽然比 gets() 安全,但安全是要付出代价的,代价就是它的使用比 gets() 要麻烦一点,有三个参数。它的功能是从 stream 流中读取 size 个字符存储到字符指针变量 s 所指向的内存空间。它的返回值是一个指针,指向字符串中第一个字符的地址。
其中:s 代表要保存到的内存空间的首地址,可以是字符数组名,也可以是指向字符数组的字符指针变量名。size 代表的是读取字符串的长度。stream 表示从何种流中读取,可以是标准输入流 stdin,也可以是文件流,即从某个文件中读取,这个在后面讲文件的时候再详细介绍。标准输入流就是前面讲的输入缓冲区。所以如果是从键盘读取数据的话就是从输入缓冲区中读取数据,即从标准输入流 stdin 中读取数据,所以第三个参数为 stdin。
1.11 fputs();
函数简介——
C 库函数 int fputs(const char *str, FILE *stream) 把字符串写入到指定的流 stream 中,但不包括空字符。
函数原型——
int fputs(const char *str, FILE *stream)
它的参数——
- str -- 这是一个数组,包含了要写入的以空字符终止的字符序列。
- stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符串的流。
返回值类型——
该函数返回一个非负值,如果发生错误则返回 EOF。
测试样例——
# include <stdio.h>
int main(void)
{
char str[20]; /*定义一个最大长度为19, 末尾是'\0'的字符数组来存储字符串*/
printf("请输入一个字符串:");
fgets(str, 19, stdin); /*从输入流stdin中读取19个字符到字符数组str中*/
fputs(str, stdout); //将字符数组的内容输出到输出流stdout中
return 0;
}
输出样例——
请输入一个字符串:i love you
i love you
Press any key to continue
需要注意的地方——
fputs() 和 puts() 有两个小区别:
- puts() 只能向标准输出流输出,而 fputs() 可以向任何流输出。
- 使用 puts() 时,系统会在自动在其后添加换行符;而使用 fputs() 时,系统不会自动添加换行符。
那么这是不是意味着使用 fputs() 时就要在后面添加一句“printf("\n");”换行呢?看情况!如果输入时使用的是 gets(),那么就要添加 printf 换行;但如果输入时用的是 fgets(),则不需要。
因为使用 gets() 时,gets() 会将回车读取出来并丢弃,所以换行符不会像 scanf 那样被保留在缓冲区,也不会被 gets() 存储;而使用 fgets() 时,换行符会被 fgets() 读出来并存储在字符数组的最后,这样当这个字符数组被输出时换行符就会被输出并自动换行。
但是也有例外,比如使用 fgets() 时指定了读取的长度,如只读取 5 个字符,事实上它只能存储 4 个字符,因为最后还要留一个空间给 '\0',而你却从键盘输入了多于 4 个字符,那么此时“敲”回车后换行符就不会被 fgets() 存储。数据都没有地方存放,哪有地方存放换行符呢!此时因为 fgets() 没有存储换行符,所以就不会换行了。
1.12 fclose();
函数简介——
fclose是一个函数名,功能是关闭一个流。注意:使用fclose()函数就可以把 缓冲区内最后剩余的数据输出到内核缓冲区,并释放 文件指针和有关的缓冲区。
函数原型——
:int fclose( FILE *fp );
返回值类型——
如果流成功关闭,fclose 返回 0,否则返回EOF(-1)。(如果流为NULL,而且程序可以继续执行,fclose设定error number给EINVAL,并返回EOF。)
int fclose(FILE *stream)
函数调用格式——
fclose(fileID)
fclose('all')
status = fclose(___)
测试样例——
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("file.txt", "w");
fprintf(fp, "%s", "这里是 runoob.com");
fclose(fp);
return(0);
}
我们编译并运行上面的程序,这将创建一个文件 file.txt,然后写入下面的文本行,最后使用 fclose() 函数关闭文件。
输出样例——
这里是 runoob.com
1.13 clearerr();
函数简介 ——
C 库函数 void clearerr(FILE *stream) 清除给定流 stream 的文件结束和错误标识符。
函数原型 ——
void clearerr(FILE *stream)
函数调用格式——
void clearerr(
FILE *stream
);
返回值类型——
这不会失败,且不会设置外部变量 errno,但是如果它检测到它的参数不是一个有效的流,则返回 -1,并设置 errno 为 EBADF。
测试样例——
// crt_clearerr.c
// This program creates an error
// on the standard input stream, then clears
// it so that future reads won't fail.
#include <stdio.h>
int main( void )
{
int c;
//此程序创建错误
//在标准输入流上,然后清除
//这样将来的读取就不会失败。
#include <stdio.h>
int main( void )
{
int c;
//通过写入标准输入来创建错误。
putc( 'c', stdin );
if( ferror( stdin ) )
{
perror( "Write error" );
clearerr( stdin );
}
//查看读取是否会导致错误。
printf( "Will input cause an error? " );
c = getc( stdin );
if( ferror( stdin ) )
{
perror( "Read error" );
clearerr( stdin );
}
else
printf( "No read error\n" );
}
putc( 'c', stdin );
if( ferror( stdin ) )
{
perror( "Write error" );
clearerr( stdin );
}
// 查看读取是否会导致错误。
printf( "Will input cause an error? " );
c = getc( stdin );
if( ferror( stdin ) )
{
perror( "Read error" );
clearerr( stdin );
}
else
printf( "No read error\n" );
}
输出输出样例——
输入
Input
n
输出
Output
Write error: No error Will input cause an error? n No read error
补 充——
clearerr的作用是使文件错误标志和文件结束标志置为0.假设在调用一个输入输出函数时出现了错误,ferror函数值为一个非零值。在调用clearerr(fp)后,ferror(fp)的值变为0。
1.14 feof();
函数简介——
eof()是检测流上的文件结束符的函数,如果文件结束,则返回非0值,否则返回0
feof()的原理
1.EOF
EOF是一个计算机术语,为End Of File的缩写,在操作系统中表示资料源无更多的资料可读取。资料源通常称为档案或串流。通常在文本的最后存在此字符表示资料结束。这个定义的意思是,文档的结尾都有一个隐藏字符”EOF”,当程序读取它的时候,就会知道文件已经到达结尾。通常使用while循环加EOF判断作为读取结束的标志。EOF 的值通常为 -1,但它依系统有所不同。2.feof()
feof()的原理:
feof()函数,并不是通过读取到文件的EOF来评判,这个文件是否为空。
对feof()来说,它的工作原理是,站在光标所在位置,向后看看还有没有字符。如果有,返回0;如果没有,返回非0。它并不会读取相关信息,只是查看光标后是否还有内容。
直接使用时的错误分析:
对于一个空文件来说,当程序打开它的时候,它的光标会停在文件的开头,但是由于文件里什么内容都没有存(但是EOF是存在的),即整个文件就存贮了一个EOF。当程序打开文件,并直接调用feof()时,这个函数就会站在光标的位置向后张望,结果就看见了EOF,然后就当然返回0了。
函数原型——
int feof(FILE *stream)
测试用例——
#include<stdio.h>
int main(void)
{
FILE *p;
p = fopen("open.txt", "r");
getc(p);
if (feof(p))
{
printf("文件为空。");
}
else
{
rewind(p);//将光标跳回到文件开头
int a;
fscanf(p,"%d",&a);
printf("%d", a);
}
return 0;
}
案例总结——
对于文件来说,无论是空文件,还是存有信息的文件,当文件被打开,光标处于默认的开头时,光标后都有信息,这时候调用feof()来查看光标后是否还有内容,就没意义。
所以我们需要从相同中找不同,先使用getc(),从文件中读取一个字符,让光标向后移动一个字符。这时空文件的光标就已经移动到EOF的后面,这时使用feof()就会返回1了。这才是feof()的正确用法。
但是要注意,一定要将光标回到文件的开头,因为之前判断文件是否为空时,将光标向前移动了一位,必须要将光标恢复到开头,这样才能保证文件的正常读取。
1.15 ferror();
函数简介——
C库函数 int ferror(FILE *stream)测试给定的流中的错误标记。
函数原型——
int ferror(FILE *stream)
它的参数——
stream -- 这是一个文件 FILE 对象的标识流的指针。
返回值类型——
如果错误指示灯与流关联的设置,函数返回一个非零值,否则,它返回一个零值。
测试样例——
#include <stdio.h>
int main()
{
FILE *fp;
char c;
fp = fopen("file.txt", "w");
c = fgetc(fp);
if( ferror(fp) )
{
printf("Error in reading from file : file.txt
");
}
clearerr(fp);
if( ferror(fp) )
{
printf("Error in reading from file : file.txt
");
}
fclose(fp);
return(0);
}
假设我们有一个文本文件 file.txt,它是一个空文件。让我们编译并运行上面的程序,因为我们试图读取一个以只写模式打开的文件,这将产生以下结果。
Error reading from file "file.txt"
1.16 fflush();
函数简介——
C 库函数 int fflush(FILE *stream) 刷新流 stream 的输出缓冲区。
函数原型——
int fflush(FILE *stream)
它的参数——
- stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个缓冲流
返回值类型——
如果成功,该函数返回零值。如果发生错误,则返回 EOF,且设置错误标识符(即 feof)。
测试样例——
#include <stdio.h>
#include <string.h>
int main()
{
char buff[1024];
memset( buff, '\0', sizeof( buff ));
fprintf(stdout, "启用全缓冲\n");
setvbuf(stdout, buff, _IOFBF, 1024);
fprintf(stdout, "这里是CSDN大家庭\n");
fprintf(stdout, "该输出将保存到 buff\n");
fflush( stdout );
fprintf(stdout, "这将在编程时出现\n");
fprintf(stdout, "最后休眠五秒钟\n");
sleep(5);
return(0);
}
让我们编译并运行上面的程序,这将产生以下结果。在这里,程序把缓冲输出保存到 buff,直到首次调用 fflush() 为止,然后开始缓冲输出,最后休眠 5 秒钟。它会在程序结束之前,发送剩余的输出到 STDOUT。
输出样例——
启用全缓冲
这里是 runoob.com
该输出将保存到 buff
这将在编程时出现
最后休眠五秒钟
1.17 fgetpos();
函数简介——
C 库函数 int fgetpos(FILE *stream, fpos_t *pos) 获取流 stream 的当前文件位置,并把它写入到 pos。
将文件指针定位在pos指定的位置上。该函数的功能与前面提到的fgetpos相反,是将文件指针fp按照pos指定的位置在文件中定位。pos值以内部格式存储,仅由fgetpos和fsetpos使用。
函数原型——
int fgetpos(FILE *stream, fpos_t *pos)
它的参数——
- stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
- pos -- 这是指向 fpos_t 对象的指针
返回值类型——
如果成功,该函数返回零。如果发生错误,则返回非零值。
测试样例——
#include <stdio.h>
void main( void )
{
FILE *fp;
fpos_t pos;
char buffer[50];
if( (fp = fopen( "test.txt", "rb" )) == NULL )
printf( "Trouble opening file/n" );
else
{
pos = 10;
if( fsetpos( fp, &pos ) != 0 )
perror( "fsetpos error" );
else
{
fread( buffer, sizeof( char ), 16, fp );
printf( "16 bytes at byte %ld: %.16s/n", pos, buffer );
}
}
fclose( fp );
}
输出详解——
首先,程序以只读方式打开名为test.txt的文件。在这里,test.txt文件中已存入字符串This is a test for testing the function of fsetpos.
(2)将pos设置为10。应用fsetpos函数将文件指针fp按照pos指定的位置在文件中定位。这样文件指针fp指向字符串中test的字母t。
(3)再从新定位的文件指针开始读取16个字符到buffer缓冲区,也就是说读取字符串"test for testing"到缓冲区buffer。
(4)最后显示结果:16 bytes at byte 10: test for testing 。
1.18 fopen();
函数简介——
C 库函数 FILE *fopen(const char *filename, const char *mode) 使用给定的模式 mode 打开 filename 所指向的文件。
函数原型——
FILE *fopen(const char *filename, const char *mode)
返回值类型——
函数返回一个 FILE 指针。否则返回 NULL,且设置全局变量 errno 来标识错误。
它的参数——
模式 | 描述 |
---|---|
"r" | 打开一个用于读取的文件。该文件必须存在。 |
"w" | 创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。 |
"a" | 追加到一个文件。写操作向文件末尾追加数据。如果文件不存在,则创建文件。 |
"r+" | 打开一个用于更新的文件,可读取也可写入。该文件必须存在。 |
"w+" | 创建一个用于读写的空文件。 |
"a+" | 打开一个用于读取和追加的文件。 |
测试样例——
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * fp;
fp = fopen ("file.txt", "w+");
fprintf(fp, "%s %s %s %d", "We", "are", "in", 2014);
fclose(fp);
return(0);
}
输出样例——
We are in 2014
PS:
二进制和文本模式的区别
1.在windows系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。
2.在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。
1.19 fread();
函数简介——
C 库函数 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) 从给定流 stream 读取数据到 ptr 所指向的数组中。
函数原型——
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
返回值类型——
成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾。
作用——
read函数的作用是从文件里读内容到程序中,它的参数意思是:
第一个参数ptr表示盛放内容的首地址;
第二个参数size表示每个元素的大小,单位还是字节;
第三个参数nmem表示要读取的元素个数;
第四个参数stream表示的是文件指针,即从哪个文件中读取。
返回值则是表示读取元素的个数,与nmemb一致表示读取成功,否则失败。
测试样例——
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
char c[] = "This is runoob";
char buffer[20];
/* 打开文件用于读写 */
fp = fopen("file.txt", "w+");
/* 写入数据到文件 */
fwrite(c, strlen(c) + 1, 1, fp);
/* 查找文件的开头 */
fseek(fp, 0, SEEK_SET);
/* 读取并显示数据 */
fread(buffer, strlen(c)+1, 1, fp);
printf("%s\n", buffer);
fclose(fp);
return(0);
}
输出样例——
This is runoob
需要注意的地方——
需要注意文件的打开方式,以及保证文件中有数据,并且buffer空间足够大才可以,大家可以上机实验。
1.20 freopen();
函数简介——
C 库函数 FILE *freopen(const char *filename, const char *mode, FILE *stream) 把一个新的文件名 filename 与给定的打开的流 stream 关联,同时关闭流中的旧文件。
函数原型——
FILE *freopen(const char *filename, const char *mode, FILE *stream)
返回值类型——
如果文件成功打开,则函数返回一个指针,指向用于标识流的对象。否则,返回空指针。
它的参数——
模式 | 描述 |
---|---|
"r" | 打开一个用于读取的文件。该文件必须存在。 |
"w" | 创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。 |
"a" | 追加到一个文件。写操作向文件末尾追加数据。如果文件不存在,则创建文件。 |
"r+" | 打开一个用于更新的文件,可读取也可写入。该文件必须存在。 |
"w+" | 创建一个用于读写的空文件。 |
"a+" | 打开一个用于读取和追加的文件。 |
测试样例——
#include <stdio.h>
int main ()
{
FILE *fp;
printf("该文本重定向到 stdout\n");
fp = freopen("file.txt", "w+", stdout);
printf("该文本重定向到 file.txt\n");
fclose(fp);
return(0);
}
让我们编译并运行上面的程序,这将发送下列行到标准输出 STDOUT,因为起初我们并没有打开标准输出:
该文本重定向到 stdout
调用 freopen() 之后,它会关联标准输出 STDOUT 到文件 file.txt,无论我们在标准输出 STDOUT 中写了什么都会被写入 file.txt,所以文件 file.txt 将有以下内容。
该文本重定向到 file.txt
使用下面的程序查看上面文件的内容
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("file.txt","r");
while(1)
{
c = fgetc(fp);
if( feof(fp) )
{
break ;
}
printf("%c", c);
}
fclose(fp);
return(0);
1.21 fseek();
函数简介——
C 库函数 int fseek(FILE *stream, long int offset, int whence) 设置流 stream 的文件位置为给定的偏移 offset,参数 offset 意味着从给定的 whence 位置查找的字节数。
函数原型——
int fseek(FILE *stream, long int offset, int whence)
它的参数——
- stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
- offset -- 这是相对 whence 的偏移量,以字节为单位。
- whence -- 这是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:
常量 | 描述 |
---|---|
SEEK_SET | 文件的开头 |
SEEK_CUR | 文件指针的当前位置 |
SEEK_END | 文件的末尾 |
返回值类型——
如果成功,则该函数返回零,否则返回非零值。
测试样例——
#include <stdio.h>
#include <stdlib.h>//fseek函数调用
int main()
{
// 开始文件中的内容为aaaaaaaaa
FILE * fp = fopen("a.txt", "r+");
if (fp == NULL) {
printf("file error\n");
exit(1);
}
fseek(fp, 2, SEEK_SET);//光标移到文件开始起第二个字节处。
fwrite("yun", 1, 3, fp); //文件内写入内容yun
fclose(fp);
return 0;
}
运行前——
运行后结果——
1.22 fsetpos();
函数简介——
C 库函数 int fsetpos(FILE *stream, const fpos_t *pos) 设置给定流 stream 的文件位置为给定的位置。参数 pos 是由函数 fgetpos 给定的位置。
函数原型 ——
int fsetpos(FILE *stream, const fpos_t *pos)
它的参数——
- stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
- pos -- 这是指向 fpos_t 对象的指针,该对象包含了之前通过 fgetpos 获得的位置。
返回值类型——
如果成功,该函数返回零值,否则返回非零值,并设置全局变量 errno 为一个正值,该值可通过 perror 来解释。
测试样例——
#include <stdio.h>
int main ()
{
FILE *fp;
fpos_t position;
fp = fopen("file.txt","w+");
fgetpos(fp, &position);
fputs("Hello, World!", fp);
fsetpos(fp, &position);
fputs("这将覆盖之前的内容", fp);
fclose(fp);
return(0);
}
输出样例——
让我们编译并运行上面的程序,这将创建一个文件 file.txt,它的内容如下。首先我们使用 fgetpos() 函数获取文件的初始位置,接着我们向文件写入 Hello, World!,然后我们使用 fsetpos() 函数来重置写指针到文件的开头,重写文件为下列内容:
这将覆盖之前的内容
使用该程序查看上面文件的内容——
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("file.txt","r");
while(1)
{
c = fgetc(fp);
if( feof(fp) )
{
break ;
}
printf("%c", c);
}
fclose(fp);
return(0);
}
1.23 ftell();
函数介绍——
函数 ftell() 用于得到文件位置指针当前位置相对于文件首的偏移字节数。在随机方式存取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。使用fseek函数后再调用函数ftell()就能非常容易地确定文件的当前位置。
ftell(fp);利用函数 ftell() 也能方便地知道一个文件的长。如以下语句序列: fseek(fp, 0L,SEEK_END); len =ftell(fp)+1; 首先将文件的当前位置移到文件的末尾,然后调用函数ftell()获得当前位置相对于文件首的位移,该位移值等于文件所含字节数
函数原型——
long int ftell(FILE *stream)
返回值类型——
该函数返回位置标识符的当前值。如果发生错误,则返回 -1L,全局变量 errno 被设置为一个正值。
测试样例——
#include <stdio.h>
int main ()
{
FILE *fp;
int len;
fp = fopen("file.txt", "r");
if( fp == NULL )
{
perror ("打开文件错误");
return(-1);
}
fseek(fp, 0, SEEK_END);
len = ftell(fp);
fclose(fp);
printf("file.txt 的总大小 = %d 字节\n", len);
return(0);
}
输出样例——
假设我们有一个文本文件 file.txt,它的内容如下:
This is runoob.com
让我们编译并运行上面的程序,如果文件内容如上所示,这将产生以下结果,否则会根据文件内容给出不同的结果:
file.txt 的总大小 = 19 字节
1.24 fwrite();
函数简介——
write() 是 C 语言标准库中的一个文件处理函数,功能是向指定的文件中写入若干数据块,如成功执行则返回实际写入的数据块数目。该函数以二进制形式对文件进行操作,不局限于文本文件。
函数原型——
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
函数用法——
(1)buffer:是一个指针,对fwrite来说,是要获取数据的地址;
(2)size:要写入内容的单字节数;
(3)count:要进行写入size字节的数据项的个数;
(4)stream:目标文件指针;
(5)返回实际写入的数据项个数count。
说明:写入到文件的哪里? 这个与文件的打开模式有关,如果是w+,则是从file pointer指向的地址开始写,替换掉之后的内容,文件的长度可以不变,stream的位置移动count个数;如果是a+,则从文件的末尾开始添加,文件长度加大。
fseek对此函数有作用,但是fwrite函数写到用户空间缓冲区,并未同步到文件中,所以修改后要将内存与文件同步可以用fflush(FILE *fp)函数同步。
返回值类型——
返回实际写入的数据块数目
测试样例——
#include<stdio.h>
int main ()
{
FILE *fp;
char str[] = "This is runoob.com";
fp = fopen( "file.txt" , "w" );
fwrite(str, sizeof(str) , 1, fp );
fclose(fp);
return(0);
}
让我们编译并运行上面的程序,这将创建一个文件 file.txt,它的内容如下:
This is runoob.com
使用下面的程序查看上面文件的内容
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("file.txt","r");
while(1)
{
c = fgetc(fp);
if( feof(fp) )
{
break ;
}
printf("%c", c);
}
fclose(fp);
return(0);
}
1.25 remove();
函数简介——
C 库函数 int remove(const char *filename) 删除给定的文件名 filename,以便它不再被访问。
函数原型——