前言
🎃你好,我是breeze亭瞳
🧐刚学完C语言基础,开始接触第一个小项目的时候,遇到了下面几个函数,感觉比较通用,但是对于初学者来说可能不太熟悉,就整理了一下。
声明一下,以下函数都是基于Windows系统,和C语言做的整理,有些在其他系统或者其他编程语言下也是可以使用的,只是我并没有写进来,有些专业的解释,我会进行一些简化
🐳system函数
system函数需加头文件<stdlib.h>后方可调用。
函数名: system
功 能: 发出一个DOS命令
头文件: #include<stdlib.h>
用 法: int system(char *command);
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
printf("About to spawn and run a DOS command\n");
system("dir");
return 0;
}
✨system(“pause”)
可以实现冻结屏幕,便于观察程序的执行结果;
✨system(“CLS”)
可以实现清屏操作。
✨system(“color 0A”);
调用color函数可以改变控制台的前景色和背景,具体参数在下面说明。
- 第一个对应于背景,第二个对应于前景。
0是背景色代号,A是前景色代号。这里的背景色和前景色可以是下面表格的任意一种
- 因为颜色属性由两个十六进制数字指定,所以颜色代号是 数字0-9✖️字母A-F
👕各颜色代码如下:
0=黑色 | 1=蓝色 | 2=绿色 | 3=湖蓝色 |
---|---|---|---|
4=红色 | 5=紫色 | 6=黄色 | 7=白色 |
8=灰色 | 9=亮蓝色 | A=亮绿色 | B=亮湖蓝色 |
C=亮红色 | D=亮紫色 | E=亮黄色 | F=亮白色 |
例一:
C语言调用DOS命令实现定时关机:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int print()
{
printf(" ╪╪╪╪╪╪╧╧╧╧╧╧╧╧╪╪╪╪╪╪\n");
printf("╔═══╧╧C语言关机程序 ╧╧═══╗\n");
printf("║※1.实现10分钟内的定时关闭计算机 ║\n");
printf("║※2.立即关闭计算机 ║\n");
printf("║※3.注销计算机 ║\n");
printf("║※0.退出系统 ║\n");
printf("╚═════════════════╝\n");
return 0;
}
int main()
{
system("title C语言关机程序");//设置cmd窗口标题
system("mode con cols=48 lines=25");//窗口宽度高度
system("color 0B");
system("date /T");
system("TIME /T");
char cmd[20]="shutdown -s -t ";
char t[5]="0";
print();
int c;
scanf("%d",&c);
getchar();
switch(c)
{
case 1:printf("您想在多少秒后自动关闭计算机?(0~600)\n");scanf("%s",t);
system(strcat(cmd,t));break;
case 2:system("shutdown -p");break;
case 3:system("shutdown -l");break;
case 0:break;
default:printf("Error!\n");
}
system("pause");
exit(0);
}
例二:
用C语言删除文件,例如文件的位置是d:\123.txt
用system()函数执行windows命令。
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
system("del d:\\123.txt");
return 0;
}
🐳fopen函数
头文件: #include <stdio.h>
函数功能: 打开一个文件
函数原型: FILE *fopen(const char *filename, const char *mode);
参数: filename
– 这是 C 字符串,包含了要打开的文件名称。 mode
– 这是 C 字符串,包含了文件访问模式。
返回值: 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在error中。
✨FILE *fopen(const char *filename, const char *mode);
使用给定的模式 mode 打开 filename 所指向的文件。文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在 error 中。
一般而言,打开文件后会做一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以一般在 fopen() 后作错误判断及处理。
参数说明
参数mode字符串包含了文件访问模式,欲打开的文件路径及文件名,参数 mode 字符串则代表着流形态。
👕mode 有下列几种形态字符串:
以 x 结尾的模式为独占模式,文件已存在或者无法创建(一般是路径不正确)都会导致 fopen 失败。文件以操作系统支持的独占模式打开。
🎿上述的形态字符串都可以加一个 b 字符
加入 b 字符用来告诉函数库以二进制模式打开文件。如 rb、w+b 或 ab+ 等组合
🎿上述的形态字符串如果不加 b
表示默认加了 t,即 rt、wt,其中 t 表示以文本模式打开文件。
由 fopen() 所建立的新文件会具有 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666) 权限,此文件权限也会参考umask值。
有些C编译系统可能不完全提供所有这些功能,有的C版本不用"r+"、"w+"、"a+",而用"rw"、"wr"、"ar"等,需要注意一下所用系统的规定。
🎿二进制和文本模式的区别
- 在Windows系统中,文本模式下,文件以"\r\n"代表换行。
🧐若以文本模式打开文件,并用 fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n"。 - 在类 Unix/Linux 系统中文本模式下,文件以"\n"代表换行。
🧐 所以 Linux 系统中在文本模式和二进制模式下并无区别。
✨打开方式总结:
各种打开方式主要有三个方面的区别:
1、打开是否为二进制文件,用“b”标识。
2、读写的方式,有以下几种:只读、只写、读写、追加只写、追加读写这几种方式。
3、对文件是否必 须存在、以及存在时是清空还是追加,会有不同的响应。具体判断如下图所示。
✨⭐在文件操作时,需要注意以下几点问题:
- 在定义文件指针时,要将文件指针指向空;如
FILE *fp = NULL
; - 在文件操作完成后,需要将文件关闭,一定要注意,否则会造成文件所占用内存泄漏和在下次访问文件时出现问题。
- 文件关闭后,需要将文件指针指向空,这样做会防止出现游离指针,而对整个工程造成不必要的麻烦;如:
fp = NULL
;
示例一:
#include <stdio.h>
#define F_PATH "d:\\myfile\\file.dat"
int main(void)
{
FILE *fp = NULL; //定义文件指针时,将文件指针指向空
fp = fopen(F_PATH, "r");//r以只读方式打开文件,该文件必须存在
if (NULL == fp)
{
return -1; //要返回错误代码
}
fclose(fp);//关闭文件
fp = NULL; //需要指向空,否则会指向原打开文件地址
return 0;
}
示例二:
#include <stdio.h>
#include <stdlib.h> //为了使用exit()
int main(void)
{
int i = 0; //用于 putchar & getc 的数据接收
char ch = ' ';
FILE *fp = NULL;//定义文件指针时,将文件指针指向空
char fname[50]; //用于存放文件名
printf("输入文件名:");
scanf("%s", fname);
fp = fopen(fname, "r"); //只供读取
if (NULL == fp) //如果失败了
{
printf("错误!");
exit(1); //中止程序
}
while ((ch = getc(fp)) != EOF)
{
putchar(ch);
i ++;
}
fclose(fp); //关闭文件
fp = NULL; // 需要指向空,否则会指向原打开文件地址
return 0;
}
示例三:
#include <stdio.h>
FILE *stream, *stream2;
int main(void)
{
int numclosed; /* Open for read (will fail if file "crt_fopen.c" does not exist) */
if ((stream = fopen("crt_fopen.c", "r")) == NULL) /* C4996 */
//Note: fopen is deprecated; consider using fopen_s instead
printf("The file `crt_fopen.c' was not opened\n");
else
printf("The file `crt_fopen.c' was opened\n"); /* Open for write */
if ((stream2 = fopen("data2", "w+")) == NULL) /* C4996 */
printf("The file `data2' was not opened\n");
else
printf("The file `data2' was opened\n");
/* Closes tream if it is not NULL */
if (stream)
{
if (fclose(stream))
{
printf("The file `crt_fopen.c' was not closed\n");
}
}
/* All other files are closed: */
numclosed = _fcloseall();
printf("Number of files closed by _fcloseall: %u\n", numclosed);
}
🐳fwrite函数
头文件: #include<stdio.h>
功能: 写入数据,把ptr所指向的数组中的数据写入到给定流stream中。
函数原型: size_t fwrite(const void *ptr
, size_t size
, size_t nmemb
, FILE *stream
)
用法:
(1)ptr
:是一个指针,对fwrite来说,是要获取数据的地址;
(2)size
:要写入内容的单字节数;
(3)count
:要进行写入size字节的数据项的个数;
(4)stream
:目标文件指针;
(5)返回实际写入的数据项个数count。
✨说明:写入到文件的哪里?
这个与文件的打开模式有关,
- 如果是w+,则是从file pointer指向的地址开始写,替换掉之后的内容,文件的长度可以不变,stream的位置移动count个数;
- 如果是a+,则从文件的末尾开始添加,文件长度加大。
fseek对此函数有作用,但是fwrite函数写到用户空间缓冲区,并未同步到文件中,所以
修改后要将内存与文件同步可以用fflush(FILE *fp)函数同步。
🐳fseek函数
头文件:#include <stdio.h>
用 法: int fseek(FILE *stream
, long offset
, int fromwhere
);
功 能:
重定位流(数据流/文件)上的文件内部位置指针
注意:文件指针指向文件/流。位置指针指向文件内部的字节位置,随着文件的读取会移动,文件指针如果不重新赋值将不会改变或指向别的文件。
描 述:
函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件2(SEEK_END))
fseek函数和lseek函数类似,但lseek返回的是一个off_t数值,而fseek返回的是一个整型。
#include <stdio.h>
long filesize(FILE*stream);
int main(void)
{
FILE *stream;
stream=fopen("MYFILE.TXT","wb+");
fprintf(stream,"Thisisatest");
printf("FilesizeofMYFILE.TXTis%ldbytes\n",filesize(stream));
fclose(stream);
return 0;
}
long filesize(FILE*stream)
{
long curpos,length;
curpos=ftell(stream);
fseek(stream,0L,SEEK_END);
length=ftell(stream);
fseek(stream,curpos,SEEK_SET);
return length;
}
✨int fseek( FILE *stream, long offset, int origin );
第一个参数stream为文件指针
第二个参数offset为偏移量,正数表示正向偏移,负数表示负向偏移
第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END依次为0,1和2
.
简言之:
fseek(fp,100L,0); 把stream指针移动到离文件开头100字节处;
fseek(fp,100L,1); 把stream指针移动到离文件当前位置100字节处;
fseek(fp,-100L,2); 把stream指针退回到离文件结尾100字节处。
#include<stdio.h>
#define N 5
typedef struct student{
long sno;
char name[10];
float score[3];
}STU;
void fun(char*filename,STU n)
{
FILE*fp;
fp=fopen(filename,"rb+");
fseek(fp,-1L*sizeof(STU),SEEK_END);
fwrite(&n,sizeof(STU),1,fp);
fclose(fp);
}
int main()/*修改覆盖最后一个学生数据*/
{
STU t[N]={
{10001,"MaChao",91,92,77},
{10002,"CaoKai",75,60,88},
{10003,"LiSi",85,70,78},
{10004,"FangFang",90,82,87},
{10005,"ZhangSan",95,80,88}
};
STU n={10006,"ZhaoSi",55,70,68},ss[N];
int i,j;FILE*fp;
fp=fopen("student.dat","wb");
fwrite(t,sizeof(STU),N,fp);
fclose(fp);
fp=fopen("student.dat","rb");
fread(ss,sizeof(STU),N,fp);
fclose(fp);
printf("\nThe original data:\n\n");
for(j=0;j<N;j++)
{
printf("\nNo:%ldName:%-8sScores:",ss[j].sno,ss[j].name);
for(i=0;i<3;i++)
printf("%6.2f",ss[j].score[i]);
printf("\n");
}
fun("student.dat",n);
printf("\nThe data after modifing:\n\n");
fp=fopen("student.dat","rb");
fread(ss,sizeof(STU),N,fp);
fclose(fp);
for(j=0;j<N;j++)
{
printf("\nNo:%ldName:%-8sScores:",ss[j].sno,ss[j].name);
for(i=0;i<3;i++)
printf("%6.2f",ss[j].score[i]);
printf("\n");
}
return 0;
}
最后
如有错误或是不妥的地方,麻烦各位及时指出,多谢🥳
🕊️ 创作不易,希望各位大佬支持一下 \textcolor{orange}{创作不易,希望各位大佬支持一下} 创作不易,希望各位大佬支持一下
👍 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!