“祭”我的大一C语言期末大作业之奇奇怪怪的知识一

“祭”我的大一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里大佬提供的目录模板,真挺香的,爱了爱了。

这次学习同学们的代码也是想有意识地想学习同学们的写程序思路,不过确实有点点困难。加油加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值