《Linux C编程环境》 课程大实验 及近期练习题:计算器,复写机,目录树创建,批处理执行器,扫雷
《Linux C编程环境》 课程大实验 及近期练习题:计算器,复写机,目录树创建,批处理执行器,扫雷
之前作业的题了,征求了老师的意见,同意我把个人解析放开公布,再提交作业已经无效了。网上可搜不到这些题。
2021年1月8日更新:删除了部分代码,防止抄袭
2021年1月13日更新:完整内容放至个人博客,感兴趣可以联系我。大一的学习,首先要靠自己努力。
个人博客:ZXJyMHIudG9wL2FydGljbGUvbGludXhwcm9ncmFtbWUv
问题名称:计算器
交互场景:
程序读input.txt文件,逐行完成文件中计算指令,将每一步的执行结果输出到output.txt文件中去。
Input.txt文件内容举例:
123+234*2
对应的output.txt文件内容举例:
357714
思路过程:
C语言最后一章讲了数据持久化——文件,不知道同学们有没有思考下何谓数据持久化?这也是文件的意义。
首先定义文件指针fpr来读取文件,fpw来输出文件,并用标准格式fopen打开,创建文件。失败则有提示语句并退出。
这里注意,题目要求是当前路径下!带盘符这样的路径是绝对路径,你无法保证在其他电脑上运行时,在相应的路径下有一个input文件,所以这里用相对路径!就是在程序运行时的目录下!不需要带盘符等东西。
if((fpr=fopen("input.txt","r"))==NULL)//读取不需要写入,所以以只读打开{......exit(-1);//使用exit函数需要加头文件<stdlib.h>}if((fpw=fopen("output.txt","w"))==NULL)//输出要以写的方式创建文件......
接着定义字符串数组str和统计的数s,由于题目是计算器,input肯定是第一行一个数,第二行一个运算符再第三行一个数,以此类推,所以我构造了cal函数,里面用switch开关语句来决定进行何种运算。
//c是传入的运算符,表明要做何种运算,s是计算结果char str[20];//用来存文件再向下读一行读到的数字switch(c)//读到了运算符,再往下读一定是数字!{case '+':fgets(str,20,fpr);s+=change(str);break;......}
......//返回值即为计算结果
我们看,第一次是一个数,第二次是一个符号,第三次又是一个数,第四次又是一个符号,我们很容易发现,其实它是第一次一个数,然后就是一个符号一个数,一个符号一个数,于是我们单独处理第一个数,后面就是循环了。
先读取了input第一行,进行了加运算,给s一个初值,因为第一个是单独的数,我们就可以等价于原结果s为0,第一次运算就是0+第一行。
s=cal('+',s,fpr);
//加运算,s初值为0,返回值即为第一个数了
然后进行while循环,因为文件位置的指针到了下一行,再读取一定是一个运算符,当读取到字符不是NULL说明没结束就继续循环,
while(fgets(str,sizeof(str),fpr))
读到运算符那一行在字符串str里,现在str里有什么?
str[0]='(一个运算符)'
str[1]='\n'//换行会被读入
str[2]='\0'
调用cal函数传递读到的运算符str[0],switch开关进行计算并写入文件,最后fputc加一个换行,至此循环体结束。
fprintf(fpw,"%d",s=cal(str[0],s,fpr));......
其中计算时还用到一个小自定义的函数change,就是将字符串内容读取并转换成整形return。在cal函数里switch判断做什么运算后再进行一次读取,然后传入change,返回整形的这个数。
......while(s[i]!='\n')//换行会被读入,千万不要写s[i]!='\0'!{xxxxxx}
......
这样程序就完成了,最后fclose关闭文件。
Example Answer:
由于历届大作业题目相似,已删除答案,如有疑问可联系我或翻我博客
问题名称:复写机
交互场景:
程序读取用户的输入,是一个整数n。程序读取input.txt文件,将文件中的每个字符复写n次后,作为output.txt文件的内容写出。
键盘输入举例:
2
Input.txt文件内容举例:
AbcEfg
对应的output.txt文件内容举例:
AAbbccEEffgg
思路过程:
人类的本质是复读机!
这题比第一题简单。与第一题一样,定义文件指针fpr和fpw,读取和创建输入输出文件,失败则有提示语句并退出。
先定义n,题目要求键盘输入n,然后还是while循环,当fgets读取没返回NULL表示没结束就继续循环,读取到内容给字符串数组str,
while(fgets(str,sizeof(str),fpr))
然后构造函数write,传入数组str,文件指针fpw来输出,还有输入的n,
void write(char str[],FILE *fpw,int n)
因为我们已经读了一行内容放入字符串str,所以不必传fpr了,然后在write函数里,while循环,读取str每个字符,只要不是换行符就继续循环,
while((c=str[j++])!='\n')
然后for循环,输出n次读到的字符到output,结束后没有返回值,
for(i=0;i<n;i++)fputc(c,fpw);
回到主函数,输出一个换行符,至此循环体结束,这样就能一行一行读取str,再一个一个输出字符n次,最后fclose关闭文件,程序就完成了。
没错,就这么简单
Example Answer:
由于历届大作业题目相似,已删除答案,如有疑问可联系我或翻我博客
问题名称:目录树创建
交互场景:
程序读取用户输入的整数n,在当前目录下创建n个子目录,目录名依次为“dirx”,其中x为1-n的某个数字,每个目录中均有一个readme.txt文件,文件中的内容均为x这个数字。
没得样例
思路过程:
本题是Linux C的题,不再仅仅是C语言的题了。一样先定义文件指针fp,不过只要定义一个输出指针就行了,因为不需要读取文件,一样失败会有提示语句并退出。
首先先输入n,要创建n个子目录名字为dirx,定义字符串path表示创建的目录名,定义字符串name表示创建目录里readme.txt的名字
因为要创建n个子目录,所以就写个for循环做n次,用mkdir函数,内跟路径名和权限代码,windows下不起作用,但Linux操作系统这里用0777表示所有人都有对文件读写执行的权限。路径名path,我们赋了三个字符”dir”,因为最后一位就是1-n顺序的数,所以刚好把for循环的i用上,
scanf("%d",&n);
......
for(i=1;i<=n;i++)
{char path[xx]="dir";
...未完
我首次写代码这里只写了把i赋给path[3],即path[3]=i+'0'
//注意字符串的0不是数字0
可是后来想到了问题,如果输入的数不是一位数,而是两位数三位数,这里就会出错了(不可能一位里面存两位数)
于是我想到了函数sprintf,将int型数i转换为字符串类型
sprintf();
然后strcat连接path,这样path就是”dirx”了,x为顺序的数,每次循环都随着i变化,用mkdir函数路径为path建立子文件夹就好了。
strcat(path,num);//num看上面,是i的数字字符
mkdir(path,0777);//在path目录下建一个dirx的文件夹
//因为这里都是在for循环里的!(看上面)
然后要创建文件了,在每个目录底下,于是用strcpy函数先把path拷到name里,再用strcat函数补上”/readme.txt”,这样字符串name里就有”dirx/readme.txt”,’/'表示进目录里面
strcpy(name,path);//此时name="dirx"
strcat(name,"/readme.txt");//此时name="dirx/readme.txt"
这时候再fopen创建文件路径为name,把num也就是那个x输出到文件里,最后fclose,
if((fp=fopen(name,"w"))==NULL){exit(-1);}fputs(num,fp);//这里不用转为数字,因为即使输出数字字符我们在文件里看到的也是这个数字......
这些都在一个循环里,至此循环体结束,这样做n次循环,也就达到了题目的要求。
我做出修改的就是这题,这里要注意字符串函数的应用,同时要考虑程序会不会类似有bug的情况发生!
Example Answer:
由于历届大作业题目相似,已删除答案,如有疑问可联系我或翻我博客
问题名称:批处理执行器
交互场景:
程序读取cmd.txt文件,将cmd.txt文件中的每行执行的结果收集到output.txt文件中。
Cmd.txt文件内容举例:
pwdls | wc -w
对应的output.txt文件内容举例:
/home/ne/8
思路过程:
批处理执行器,也是Linux C的题目,有读取有输出,定义文件指针fpr和fpw,报错有提示语句并退出,这里多定义一个空文件指针temp,因为接下来要用到popen函数。定义字符串contect来读取cmd执行的结果,定义字符串str读取cmd.txt的行内容。
写一个while循环,只要fgets读到不是NULL就继续,然后用popen开管道调用fork()产生子进程,执行shell运行之前读取到str里的命令,把结果读取到空指针temp中
然后fgets读取temp到字符串connect里,这里connect就是cmd运行的结果了,我们fputs直接写入output文件中,然后pclose关闭管道
while(fgets(str,sizeof(str),fpr)){temp=popen(str,"r");fgets(xxx);fputs(xxx);pclose(temp);}
至此循环体结束,最后fclose关闭文件,问题就解决了。
如果不明白popen的用途可以看书第七章(我其实也没怎么看书,只是把函数都过一遍,然后要用啥就去看它的函数原型),或者网上搜popen函数学习。
Example Answer:
由于历届大作业题目相似,已删除答案,如有疑问可联系我或翻我博客
作业题结束了,下面另外的题了,之前有位同学问我的,我觉得比较有趣,就拿来分享一下。
问题名称:扫雷
问题描述:
扫雷游戏是一款十分经典的单机小游戏。在nn行mm列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。
现在给出nn行mm列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。
注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。
输入格式
第一行是用一个空格隔开的两个整数nn和mm,分别表示雷区的行数和列数。
接下来nn行,每行mm个字符,描述了雷区中的地雷分布情况。字符’*’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。相邻字符之间无分隔符。
输出格式
输出文件包含nn行,每行mm个字符,描述整个雷区。用’*’表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。
样例输入 #1
3 3
*??
???
?*?
样例输出 #1
*10
221
1*1
样例输入 #2
2 3
?*?
*??
样例输出 #2
2*1
*21
说明/提示
对于 100\%100%的数据, 1≤n≤100, 1≤m≤1001≤n≤100,1≤m≤100。
思路过程:
准备用一个主函数解决,看输入,先输入两个数定义雷区长宽,然后输入雷区数据,由于是符号’?‘和’*’,所以定义字符串数组s,行为n,列为m+1,因为要放’\0’。然后为了计算一个格子周围8个格子的雷数,我们定义一个整形数组a,把周围包起来,也就是行为n+2,列为m+2。
int i,j,n,m,x,k,t;scanf("%d %d",&n,&m);int a[n+2][m+2];char s[n][m+1];
例如样例输入1的
*??
???
?*?
在字符串数组s里就是
*??\0
???\0
?*?\0
先把数组a全置为0,然后对于有雷的地方我们在数组a里把它置为1
for(i=0;i<n+2;i++)for(j=0;j<m+2;j++)a[i][j]=0;for(i=0;i<n;i++)for(j=0;j<m;j++)if(s[i][j]=='*')a[i+1][j+1]++;
对于样例输入1数组a里内容
00000
01000
00000
00100
00000
真正中间3x3才是雷区,周围一圈是包起来的
然后开始运算,对于中间的3x3每个格子,如果是1,那就不动;如果是0,那就要计算雷数,这样就是对于它周围八个格子,如果有1(表明有雷),计数的x就自增,字符串s里就输入这个位置的雷数
这也是为啥数组a要包一圈雷区
for(i=0;i<n;i++)for(j=0;j<m;j++){if(a[i+1][j+1]==1)continue;x=0;//每次循环置为0for(k=0;k<=2;k++)for(t=0;t<=2;t++)if(a[i+k][j+t]==1)//这边其实是i+1+k,-1<k<1。j同理。x++;s[i][j]=x+'0';}
然后输出就行了
题目就完成了
Example Answer:
#include <stdio.h>
#include<string.h>
int main()
{int i,j,n,m,x,k,t;scanf("%d %d",&n,&m);int a[n+2][m+2];char s[n][m+1];getchar();//上面有一次scanf输入,要吃掉一个换行符,不然下面输入会有换行符到s[0][0]for(i=0;i<n;i++)gets(s[i]);//输入雷区数据for(i=0;i<n+2;i++)for(j=0;j<m+2;j++)a[i][j]=0;//数组a置0for(i=0;i<n;i++)for(j=0;j<m;j++)if(s[i][j]=='*')//雷点置为1a[i+1][j+1]++;for(i=0;i<n;i++)for(j=0;j<m;j++){if(a[i+1][j+1]==1)//如果是1,表明这地方是雷continue;//对于s就不动它,结束本层循环x=0;//计数器置0for(k=0;k<=2;k++)for(t=0;t<=2;t++)if(a[i+k][j+t]==1)//周围8格扫雷x++;//有雷就自增s[i][j]=x+'0';//把雷数的数字字符覆盖掉s内的'?'}for(i=0;i<n;i++)//最后输出{ for(j=0;j<m;j++)printf("%c",s[i][j]);putchar('\n'); }return 0;
}
本来不想写的,可是马上要编程竞赛了,又凑上期末考试,就抽时间发博客了,刚好自己也复习巩固一下算法
看了下历年算法比赛,就六道题,17年还会三道,18年不会了,保佑我今年算法比赛混个奖
祝大家期末考试都取得好成绩!
如果有问题或者错误请见谅,并联系我改正!一起努力学习!
《Linux C编程环境》 课程大实验 及近期练习题:计算器,复写机,目录树创建,批处理执行器,扫雷相关推荐
- 上千个国外免费权威优质编程学习课程大放送 —— 提升篇
随着互联网的发展,像 MIT 和斯坦福等世界名校,都开始在网上公开一些优质的在线免费课程供大家学习.到现在,已经有来自全球共 1000 所左右的学校提供了非常多的优质课程,最有名的平台就是 MOOC. ...
- 【华为云技术分享】Linux内核编程环境 (1)
在上一期中,我们介绍了Linux内核的源码结构,这一期我们介绍Linux内核编程环境,首先介绍的是Linux内核的编译方法. 一.Linux内核编译方法 本期中我们以Linux 4.19.94版内核来 ...
- 搭建Linux云编程环境
仅个人记录可参考 本篇解决你想在一台陌生的电脑上ps.Excel.word.敲代码,却无相应环境而又不想安装各种软件和设置环境变量的烦恼. 获取root权限 解bl锁→修补镜像boot→刷入trwp→ ...
- 计算器软件C语言课程设计实验报告,c简单计算器实验报告_相关文章专题_写写帮文库...
时间:2019-05-15 12:55:15 作者:admin 计算器实验报告 班级: 07计本(1)班 姓名: 王林 学号: 20706031047 指导老师: 韩静 一. 需求分析 (1)制作一个 ...
- linux 嵌入式 交叉 环境搭建 实验原理,实验三 嵌入式Linux开发环境的搭建
南京邮电大学通达学院 实 验 报 告 实验 实验三题目 嵌入式Linux开发环境的搭建 课程名称 嵌入式驱动开发实验 学院 专业 班 实验者学号同做者学号 08002210 姓名 毛骏超 同做者学号 ...
- emacs Linux Java编程环境_Linux下搭建用emacs查看代码的开发环境
在windows下面我们有source in sight可以方便的浏览大工程中的代码,切换到linux环境下开发时,我们也可以搭建一个这样的环境.下面的内容将介绍如何搭建这样一个开发环境(这里我们假设 ...
- apue.3与unp在Linux上编程环境搭建
导读 在学习Unix高级环境编程与Unix网络编程的时候,按照作者的提示操作即可成功的编译运行这两本书提供的源代码,但是如果自己想想在自己的环境里按照书籍学习,也就是在自己的环境里调用作者封装的api ...
- Linux配置编程环境+云服务器上传文件
Java环境配置 Ubuntu https://www.cnblogs.com/lfri/p/10437266.html Centos https://blog.csdn.net/qq_2107771 ...
- 【华为云技术分享】Linux内核编程环境 (2)
在上一期中,我们介绍了Linux内核编译方法,这一期我们用一个例子来介绍如何向Linux内核中增加一个模块. 一.LKM内核模块 LKM是Loadable Kernel Module的缩写,意思是可加 ...
最新文章
- GitHub使用指南——建立仓库、建立文件夹、上传图片详细教程
- 二叉树的基本特性和二叉树的几种基本操作的机制_关于二叉树,你该了解这些!...
- 李宏毅-ELMO、BERT、GPT视频笔记
- 原生js实现一个连连看小游戏(一)
- java正则表达式中的坑String.matches(regex)、Pattern.matches(regex, str)和Matcher.matches()
- HDU1760 A New Tetris Game NP态
- 解决JavaScript浮点数(小数) 运算出现Bug的方法
- JIT编译对比AOT编译(附图片)
- 我从华为身上学到的项目管理经验 -- 设计篇
- 计算机主机配置一般有机箱主板cpu,组装台式电脑配置清单
- RL 笔记(3)PPO(Proximal Policy Optimization)近端策略优化
- 第十一课 区块链常用共识算法介绍
- matlab 符号微积分
- SerialFeature
- java通过jstack命令查询日志深入理解
- 【各大公司年会奖品清单】腾讯送直升飞机,网易与日女星度过美好的下午?...
- 激光雷达学习笔记-------Ubuntu 18.04 + 思岚科技 A1M8+ ROS 上手使用及基于hector_slam 建图
- Android手游外挂入侵----寓攻于守,方能破敌
- 清华大学计算机周建宇,一曲高歌征服清华考官
- Wireshark的提示
热门文章
- 微信公众号html在线编辑器,【微信公众平台工具开发】雷人微信网页编辑器
- 【Windows MTU】Windows上最大传输单元MTU值的查看和设置
- Win7系统重装账户被禁用的解决方法
- 【.net函数式编程】可重复的执行repeatable execution
- Web端兼容性测试--浏览器/平台/分辨率
- JVAV SE学习总结(01)
- 怎样把PDF格式转换成可编辑的PPT幻灯片?
- 关于Flutter中使用 webview_flutter: 1.0.6 打开公众号连接只显示标题不显示内容的记录
- CSS3各个模块详解
- 光环:研发云搭建及人才梯队建设——姚冬