“祭”我的大一C语言期末大作业之奇奇怪怪的知识一
文章目录
前言
非常非常惭愧,完成大作业的时候,我就决定要写博客记录一下,当时甚至想记录下每一次debug的经历,现在想想太过于细碎,可能后期会分点整理一下。也因为1月还有几门考试,所以决定考完了好好写一下博客。虽然但是,考完了确实也厚着脸皮向同学、学长要了他们的作业,计划好好研究一下,不过,这个工作量着实有点超出了我的计划。 ##
任务难度主要是在这样的几个方面: ###
1、对于大家的代码认知的不到位。 对于同学们功能实现的思路了解需要时间,其实可以发现尤其是师哥的代码中使用了很多我不熟悉的函数,这些我都会尽量逐一整理为“奇奇怪怪的知识” ###
2、对于博客这种记录形式的陌生
考完试之后,其实我就已经在看大家的程序了,甚至向师哥立了flag,说14号之前一定写完,但是一拖就到了今天😵。
所以不想再拖了,干脆先把整理的一些发出了,做一个类似合辑的形式。这样每天更一点,计划迟迟得不到推进的无力感也会轻一些。
1、关于fread函数
众所周知,fread函数声明是
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
但是从下方这个代码块我们还是可以看出两个小知识点:
int main()
{
FILE*stream;
char m[]="this is a test";
char buf[20];
if((stream=fopen("dump.fil","w+"))==NULL){
fprintf(stderr,"Cannot open the file.\n");
return 1;
//防止文档为空
fwrite(m,1,sizeof(m),stream);
//在文件中写入字符串stream
fseek(stream,0,1);
//将stream指针移动到当前位置0字节处
fread(buf,1,sizeof(m),stream);
//从stream文件中读取m字节长度到buf字节数组中
printf("%s",buf);
fclose(stream);
system("pause");
return 0;
}
}
输出结果为 this is a test
(1)关于sizeof和strlen
sizeof(m)与strlen(m)-1的值其实是相等的。
其实我在csdn上查阅到很多的博文讲这两个函数
这里就上链接!
C语言中sizeof与strlen的区别总结!
(发现这里sizeof的值甚至与寄存器位数也有关系,真的是很amazing呢!)
我们可以粗糙地理解一下:
i.sizeof和strlen的返回值都是整数,不过这大概也是它们之间唯一的共同点了😉hh大概
ii.sizeof的参数可以为类型、数组、指针、函数,如sizeof可以用于测定类型所占存储单元(运行结果为4):
printf("%d",sizeof(int));
但是strlen的参数仅为数组
[^小插曲]C语言不仅有大作业,也有理论考试,考试中考了这样的一条选择题:
#define PI "hello"
问这里PI被定义为什么?
正确答案应该是字符串,可是我选的是标识符。😡
iii.sizeof的本质是运算符,strlen的本质是函数。
(2)关于fseek函数
众所周知,fseek函数的定义为
int fseek( FILE *stream, long offset, int origin );
即将stream指针以origin的位置为基准,移动offset个字节。
offset的数值正数表示正向偏移,负数表示负向偏移。
下方展示的代码块为利用stream函数得知文章的总字节长度
#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);
/*告知curpo为此时指针stream距离文件头的距离*/
fseek(stream, 0L, SEEK_END);
/*L是因为变量定义中用的是long int。*/
/*本条命令目的是把stream指针移动到文件结尾处
这条指令指设置指针stream的位置,以SEEK_END为基准,偏移0L个字节的位置
*/
length = ftell(stream);
/*这时的length应该是文件的长度*/
fseek(stream, curpos, SEEK_SET);
/*把steam指针移动到离文件头curpo距离的地方,curpo被赋值为刚开始距离文件头的初始位置*/
return length;
}
补充:
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字节处。
总结:
filesize函数利用文件中的一个stream(工具人指针)。
先定义一个long int数据类型的常量用来记录stream指针的初始位置,
接着用fseek函数将steam移动到文件末,
再定义一个long int数据类型的常量用来这时steam指针距离文件头的距离(即文件的总长),
返回值为第二个变量即得到了文件的长度。
2、检查日期输入是否合法
重点关注2月
if(month>12||month<1)
return -1;
else{
int max_day[12]={31,29,31,30,31,30,31,31,30,31,30,31}
if(day>max_day[month-1]||day<1)
return -1;
if(month == 2){
bool b;
if(year%4==0)
if(year%100)==0)
if(year%400==0)
b = 1;
else b=0;
else b = 1;
else b = 0;//闰年为1,平年为0
if(!b&&day>28)//如果b=0且day值大于28则退出
return -1;
}
}
看到这段代码时,原谅菜鸡本人还特意百度了一下闰年的判断方式:😁
(1)能被4整除,但不能被100整除;
(2)能被400整除。
3、fscanf和fprintf函数的返回值
fsanf的返回值为正常情况下从文件读出得得参数个数。
而fprintf的返回值为写入文件的字节数。
😂奇怪的知识又增加了。
好学的小伙伴可能要问了,这有什么用呢?
其实可以利用它来进行判断,从而读取文件的准确性得到了一定的保证。
这里作为while语句的执行判断:
while(fscanf(fp,"%d %d %d",&a,&b,&c)==3)
{
}
这里其实也可看作判断了一下fp文件是否为空:
while(fscanf(fp,"%d",&a))
{
}
同时,我们也可以根据返回值来判断成功读取数据的个数,
如下方的代码块,我们可以根据num的值对于fscanf是否完成了它的使命进行判断。
int num=fscanf(fp,"%d %d %d",&a);
亿点废话
这次先选取了3个小知识作为第一篇,其实这篇题目中的“祭”某一方面讲也是认真的,这学期的C语言学习,对于自己的表现,我其实是非常不满意的。师哥师姐也说,既然自己觉得学的不好,那就去做一些努力。大概是由于自己的性格,哪怕只有一点点想法,我都比较想和师哥师姐或者同学聊,尬聊也要聊😂。
所以!会争取日更,最近是真的闲的慌哈哈哈。下面是用VScode学的一点点html,第二天还下了DW,DW的界面好好看啊,太友好了叭!!
[^除了三个超链接,无任何其他功能(哈哈哈哈理直气壮)]
这篇博文也是用VScode里markdown插件写的,有一说一,下插件的感觉还真挺爽的哈哈。不过后来复制到CSDN里的编辑器来,套用了CSDN里大佬提供的目录模板,真挺香的,爱了爱了。
这次学习同学们的代码也是想有意识地想学习同学们的写程序思路,不过确实有点点困难。加油加油!