1、rewind(FILE *):回到文件开始处
2、fprintf(), fscanf(), fgets(), fputs()
(1)、fprintf(<#FILE *restrict#>, <#const char *restrict, ...#>) //return 成功写入个数
(2)、fscanf(<#FILE *restrict#>, <#const char *restrict, ...#>) //return 成功读取个数
(3)、fgets(<#char *restrict#>, <#int#>, <#FILE *#>) //遇到EOF, return NULL; 否则, return 传递给它的地址值
(4)、fputs(<#const char *restrict#>, <#FILE *restrict#>) //成功输入, 返回非负整数; 否则返回EOF
3、command + ? 注释xcode代码
4、fseek(), ftell()实现倒序读取文件内容
fseek(fp, 0L , SEEK_END); //定位到文件结尾
last = ftell(fp);
for(count = 1L; count <= last; count++){
fseek(fp, -count, SEEK_END); //回退
ch = getc(fp);
if (ch == '\r') {
putchar('\n');
}else{
putchar(ch);
}
}
5、fseek()参数
(1)第一个参数为FILE指针
(2)第二个参数为偏移量,表示从起点开始要移动的距离,必须是一个Long类型的值,可以为正(前移)、负(后移)、零(保持不动)
(3)第三个参数为模式,用来标识起点。SEEK_SET 文件开始,SEEK_CUR 当前位置, SEEK_END文件结尾
(4)如果正常,返回值为0,如果有错误,返回值为-1
6、Ftel()函数
(1)Long类型,返回文件的当前位置,返回距文件开始处的字节数亩来确定文件的位置。文件的第一个字节到文件开始处的距离是字节0,适用于以二进制模式打开的文件
7、fgetpos(), fsetpost()函数
(1)用以处理较大文件的定位函数,采用一种称为fpost_t (file position type,文件定位类型)
(2)int fgetpos(FILE * restrict stream, fpost_t * restrict pos); 被调用时,该函数在pos所指的位置放置一个fpost_t值,这个值描述了文件中的一个位置,如果成功,函数返回0,否则返回一个非零值
(3)int fsetpos(FILE * stream, const fpost_t * pos);被调用时,该函数使用pos指向的那个fpos_t值设定文件指针指向该值所指示的位置,如果成功,函数返回0,否则返回一个非零值
8、ungetc()函数
(1)int ungetc(int c, FILE *fp);
(2)将c制定的字符放回输入流中,如果向输入流中翻入了一个字符,下一次调用标准输入函数就会读入那个字符。
(3)ANSIC标准保证每次只会放回一个字符。如果一个c实现允许将一行里的多个字符放回输入流,那个输入函数就会以放回时相反的顺序来读入
9、fflush()函数
(1)int fflush(FILE *fp);
(2)将缓冲区任何未写的数据发送到一个由fp指定的输出文件中区,这个过程称为刷新缓冲区
(3)如果fp是一个空指针,将刷新掉所有的输出缓冲
(4)对于一个输入流使用fflush()函数的效果没有定义,只要最近一次使用流的操作不是输入操作,就可以对一个更新流(任何读-写模式的流)使用这个函数
10、setvbuf()函数
(1)int setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size);
(2)建立一个供标准I/O函数使用的替换缓冲区,打开文件以后,在没有对流进行任何操作以前,可以调用这个函数
(3)由指针fp来指定流,buf指向将使用的存储区,如果buf的值不是NULL,就必须创建这个缓冲区
(4)size变量为setvbuf()函数制定数组的大小
(5)mode将从下列选项中选取:
①_IOFBF,完全缓冲(缓冲区满的时候刷新)
②_IOLBF,行缓冲(缓冲区满的时候或者一个新行写入的时候)
③_IONBF,无缓冲,如果成功执行,函数会返回零值,否则返回一个非零值
11、fwrite()函数
(1)如果把数据存储在一个使用与程序具有相同表示方法的文件中,就城数据以二进制形式存储
(2)size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb, FILE * restrict fp);
(3)指针ptr是要写入的数据块的地址
(4)size表示要写入的数据块的大小(以字节为单位)
(5)nmemb表示数据块的数目
(6)fp指定要写入的文件
(7)返回成功写入的项目数,正常情况下,与Nmemb相等;若有写入错误,返回值就会小与nmemb
12、fread()函数
(1)size_t fread(void * restrict ptr, size_t size, size_t nmemb, FILE * restrict fp);
(2)ptr为读入文件数据的内存存储地址
(3)fp指定要读取的文件
(4)使用fread()函数来读取通过fwrite()写入的文件数据
(5)返回成功读入的项目数,正常情况下,与nmemb相等,读取错误的话,返回值会小于nmemb
13、综合使用
FILE *fa, *fs;
int files = 0;
char file_app[SLEN];
char file_src[SLEN];
puts("输入要追加内容的文件名:");
gets(file_app);
if ((fa = fopen(file_app, "a")) != NULL)
{
fprintf(stderr, "不能打开文件 %s", file_app);
exit(2);
}
if (setvbuf(fa, NULL, _IOFBF, BUFSIZE) != 0)
{
fputs("不能创建输出缓冲区", stderr);
exit(3);
}
puts("输入要添加内容的文件名(输入空行退出):");
while (gets(file_src) && file_src[0] != '\0')
{
if (strcmp(file_app, file_src) == 0)
{
fputs("不能追加到相同的文件", stderr);
}
else if((fs = fopen(file_src, "r")) == NULL)
{
fprintf(stderr, "不能打开源文件");
}
else
{
if(setvbuf(fs, NULL, _IOFBF, BUFSIZE) != 0)
{
fputs("不能创建源文件缓冲区", stderr);
continue;
}
append(fs, fa);
if(ferror(fs) != 0)
fprintf(stderr, "读取源文件%s时发生错误!", file_src);
if(ferror(fa) != 0) {
fprintf(stderr, "写入文件时%s发生错误", file_app);
}
fclose(fs);
files++;
printf("FILE %s appended.\n", file_src);
puts("下一个文件:(输入空行退出)");
}
}
printf("Done.%d files appended.\n", files);
fclose(fa);
return 0;
}
void append(FILE * source, FILE * dest)
{
size_t bytes;
static char temp[BUFSIZE];
while ((bytes = fread(temp, sizeof(char), BUFSIZE, source)) > 0) {
fwrite(temp, sizeof(char), BUFSIZE, dest);
}
}
14、feof()函数
(1)如果最近一次输入调用检测到文件结尾,feof()函数返回一个非零值,否则返回零值
15、ferror()函数
(2)如果发生读写错误,ferror()函数返回一个非零值,否则返回零值
16、结构声明
(1)struct 结构名{ //在main函数之上定义
普通类型 类型名[];
普通类型 类型名[];
}; //这里有分号
(2)声明结构变量:struct 结构名 变量名;
(3)初始化结构:
sturcc 结构名 变量名 = {
类型1的值,
类型2的值,
类型3的值
}; //这里有分号
(4)结构的制定初始化项目:
struct 结构名 变量名 = {
.结构里的成员名 = 值;
.结构里的成员名 = 值;
}; //这里有分号
17、结构指针
(1)struct 结构名 * 指针名;
(2)结构指针名 = &结构变量名; //一个结构的名字不是该结构的地址
(3)使用结构指针访问成员: 结构指针名->成员变量名; (结构指针名).成员变量名;
(4)函数参数使用结构地址:double sum(const struct funds * money);
(5)函数参数使用结构: double sum(struct funds moolah);
18、结构
(1)可以把两个相同结构的变量互相赋值
(2)可以作为函数返回值
(3)把指针作为参数的优点:
①可工作在较早的C上,也可以在较新的C上,执行速度快
②只须传递一个单个地址
缺点:缺少对数据的保护
(4)把结果作为参数传递的优点是函数处理的时原始数据的副本,比直接处理原始数据安全
(5)在结构中存储字符串,请使用字符数组成员。用字符指针存储,字符存储的内存空间不在结构中
19、复合文字和结构
(1) (struct 结构名){结构变量值};
20、伸缩数字成员
(1)伸缩型数组成员必须是最后一个数组成员
(2)结构中必须至少有一个其他成员
(3)伸缩型数组就像普通数组一样被声明,除了它的方括号内是空的
(4)使用malloc()函数莱维伸缩数组成员分配内存
21、将结构保持到文件
(1)使用fwrite()函数保存到文件
(2)使用fread()函数从文件读取
22、联合
(1)联合是一个能在同一个存储空间里(但不同时) 存储不同类型数据的数据类型。
(2)union 联合变量名{
普通类型 成员名;
普通类型 成员名;
}; //这里有分号
(3)把一个联合初始化为同类型的另一个联合 union 联合名 联合变量名 = 联合变量名2;
(4)初始化联合的第一个元素 union 联合名 联合变量名 = {值};
(5)制定初始化项目 union 联合名 联合变量名 = {.成员名=值, .成员名=值};
(6)点运算符表示正在使用哪种数据类型,在同一时间内只能存储一个值,即使有足够的空间,也不能同时保存一个char类型和一个int类型的值,由你负责记住当前保存在联合中的数据的类型
23、间接成员运算符 ->
(1)与指向结构或联合的指针一起使用,用来指明结构或联合的成员
24、枚举类型
(1)enum 枚举名{成员名,成员名};
(2)从技术上讲,它们是int类型的常量
(3)默认值为 enum kids{nippy, slats, skippy, liz}; 列表中的常量被指定为0, 1, 2
(4)指定值为enum feline{low = 100, lynx = 500, heigh = 20000};
(5)混合赋值:enum feline{cate, lynx = 10, puma, tiger}; cat的值为0, lynx, puma, tiger的值为10, 11, 12
25、typedef
(1)与#define不同,typedef给出的符号名称仅限于对类型,而不是对值
(2)typedef的解释由编译器,而不是预处理器执行
(3)虽然它的范围有限,但在其受限范围内,typedef比#define更灵活
(4)typedef int MyType; //接下来可用MyType来声明变量了
(5)作用于取决于typedef语句所在的位置,函数内部就是局部的,函数外部就是全局的
(6)size_t是各平台用typedef声明的变量
(7)对结构使用typedef,typedef struct complex{float real; float imag;} COMPLEX;//可以使用类型COMPLEX代替struct complex来表示复数
26、奇特的声明
(1) 表示一个指针,()表示一个函数, []表示一个数组
(2)允许使用多于1个的修饰符
①int board[8][8]; //int数组的数组
②int ptr; //指向int的指针的指针
③int risk[10]; //具有10个元素的数组,每个元素都是一个指向int的指针
④int (rusks)[10]; //一个指针,指向具有10各元素的int数组
⑤int * oof[3][4]; //一个3×4的数组,每个元素是一个指向int的指针
⑥int ( uuf)[3][4]; //一个指针,指向3×4的int数组
⑦int ( uof[3])[4]; //一个具有3各元素的数组,每个元素都是一个指向具有4个元素的int数组的指针
(3)修饰符的顺序差别:
①表示一个数组的[]和表示一个函数的()具有同样的优先级,这个优先级高于间接运算符的优先级。int risks[10];//这就意味着这个生命使得risks是一个指针数组而不是一个指向数组的指针
②[]和()都是从左到右进行结合的,int goods[12][50];//这个声明使得goods是一个由12个具有50各int值的数组构成的数组,而不是由50个具有12个int值的数组构成的数组
③[]和()具有相同的优先级,但由于它们是从左到右结合的,int ( rusk)[10];//这个声明使得rusks是一个指向具有10个int值的数组的指针
27、指向函数的指针
(1)void (pf)(char *); //pf是一个指向函数的指针
(2)void *pf(char ); //pf是返回一个指针的函数
(3)使用指向函数的指针来访问函数
①( pf)(参数);
② pf(参数);
28、c的位操作
(1)位运算符:
①按位取反:~
②按位与:&
③按位或:|
④按位异或:^
(2)移位运算符
①左移:<<
②右移:>>
(3)位字段:
struct 字段名{
unsigned int autfd:1;
unsigned int bldfc:1;
unsigned int undln:1;
} 字段变量名;
(2)如果所声明的总位数超过一个unsigned int大小,那将会使用下一个unsigned int存储位置,不允许一个字段跨越两个unsigned int之间的边界
(3)编译器自动地移位一个这样的字段定义,使字段按unsigned int边界对其,发生这种情况时,会在第一个unsigned int中留下一个未命名的洞
(4)可以使用未命名的字段宽度"填充"未命名的洞,使一个宽度为0的未命名的字段迫使下一个字段与下一个整数对齐
网友评论