问题总结:
第十周的学习任务主要是老师发在群里的代码,我在阅读了所有同学第十周的学习总结后,对大家不理解或是提出问题的代码进行了详细的分析。因为这些是很多同学共性的问题,就不对大家学号一一列举了。
1、有关echostate的问题
int main()
{
struct termios info;
int rv;
rv = tcgetattr( 0, &info ); /* read values from driver */
if ( rv == -1 ){
perror( "tcgetattr");
exit(1);
}
if ( info.c_lflag & ECHO )
printf(" echo is on , since its bit is 1\n");
else
printf(" echo is OFF, since its bit is 0\n");
return 0;
}
termios 结构体中,该结构体一般包括如下的成员:
- tcflag_t c_iflag;
- tcflag_t c_oflag;
- tcflag_t c_cflag;
- tcflag_t c_lflag;
- cc_t c_cc[NCCS];
tcgetattr是一个函数,成功返回零;失败返回非零。tcgetattr函数用于获取与终端相关的参数。参数fd为终端的文件描述符,返回的结果保存在termios 结构体中
所以,rv = tcgetattr( 0, &info );
获取的是文件描述符为0的终端的参数,并将其返回的结果保存在info结构体中
if ( rv == -1 ){
perror( "tcgetattr");
exit(1);
}
这个判断语句是判断tcgetattr函数返回是否成功,如果失败的话,通过perror函数将其失败的原因输出。成功的话执行下面的代码
info.c_lflag & ECHO
这是第二个条件语句的判断条件。 c_lflag我们前面已经提到过,是termios结构体中的成员,它是本地模式标志,控制终端编辑功能,用于控制驱动程序与用户的交互。其具体参数功能如下:
- ISIG:当输入INTR、QUIT、SUSP或DSUSP时,产生相应的信号
- ICANON:使用标准输入模式
- XCASE:在ICANON和XCASE同时设置的情况下,终端只使用大写。
- ECHO:显示输入字符
- ECHOE:如果ICANON同时设置,ERASE将删除输入的字符
- ECHOK:如果ICANON同时设置,KILL将删除当前行
- ECHONL:如果ICANON同时设置,即使ECHO没有设置依然显示换行符
- ECHOPRT:如果ECHO和ICANON同时设置,将删除打印出的字符(非POSIX)
- TOSTOP:向后台输出发送SIGTTOU信号
因此,这个判断条件是用来判断是否需要回显(echo)字符。若需要则输出“on”,否则输出“off”
2、fileinfo.c的问题:
该程序的功能为:操作文件和文件夹在文件系统中的结构,完成诸如:创建,复制,读取信息,移动,判断是否存在,删除等功能。在fileinfo.c 代码中是完成 读取信息 的功能
下面介绍程序中的一些参数,对程序具体分析:
argc定义参数的个数
argc == 1 就是说参数的个数为0.
(./fileinfo fileinfo.c中,argc=2,参数个数为1,是后面的fileinfo.c)
argv是字符串数组,存的是参数,定义为char**或者char* argv[]
另外
stat函数
函数定义:
int stat(const char *file_name, struct stat *buf);
函数功能:
通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
返回值:
执行成功则返回0,失败返回-1,错误代码存于errno
知道这些之后,我们就可以对程序进行具体的分析。首先,程序中的第一个if条件语句,它的判断条件是(argc>1)
,也就是说当我们最少输入一个参数(即argc最少为2)时,才会执行下面的语句。
接下来的if( stat(argv[1], &info) != -1 )
语句中,argv[1]中存放的是输入的第一个参数,&info是用来保存stat函数获取的文件信息的。stat(argv[1], &info) != -1
,这个判断条件是判断stat函数是否执行成功(根据stat函数的返回值)。如果成功,则执行show_stat_info函数,若失败则输出失败的原因(perror(argv[1]); )。
同时,需要注意的是,这里stat函数用的参数是argvp[1]。也就是说,不管我们输入2个或者更多的参数,它都只返回我们输入的第一个参数的文件信息。
比如,我们输入./fileinfo fileinfo.c who
,它就只会输出fileinfo.c的信息。先输入who则输出who的文件信息
如果我们把argv[1]改成argv[2],输出内容就会发生相应的变化。
最后,说明输出文件信息的具体内容:
mode:st_mode 文件的类型和存取的权限
links:st_nlink 连到该文件的硬链接数目,刚建立的文件值为1
user:st_uid 用户ID
group:st_gid 组ID
size:st_size 文件字节数
modtime:st_mtime 最后一次修改时间
name:文件名称
3、有关cp1的问题:
cp1的功能是进行文件复制。
这个代码主要会用到5个函数:open、creat、read、write(这四个函数错误时都返回-1)以及代码中定义的oops函数。它们的功能分别是:打开文件、建立文件、读文件、写文件。oops是自己定义的一个报错函数。
定义的三个参数in_fd、out_fd、n_chars分别用来存放open、creat、read函数的返回值。
argc、argv与fileinfo中相同。
首先,第一个判断语句if (argc != 3)
是用来判断是否输入完整。因为要进行文件复制,所以要输入被复制文件和复制到的文件,因此argc必须=3。如果输入错误,则会报错
接下来执行open函数,如果函数错误,用oops函数进行报错。
然后执行creat函数创建文件,如果错误,也用oops函数进行报错。
创建好新的文件之后,我们就要开始读刚刚打开的被复制文件。所以用到read函数。read函数中的参数in_fd是open的返回值,表示要对这个文件进行读操作。buf是用来存放读过的数据的。buffersize则表示每次读的字节个数。read函数返回值:返回值为实际读取到的字节数,如果返回0,表示已到达文件尾或无可读取的数据。错误返回-1,
。所以,当n_chars>0时,表示还在进行读操作。然后我们在读的同时进行写操作。if (write(out_fd, buf, n_chars) != n_chars)
则说明,只有在write函数写入的字节数与read读的字节数相同时,才不报错。
if (close(in_fd) == -1 || close(out_fd) == -1)
用来判断完成所有操作后,文件是否正常关闭。
最后说明报错函数oops:报错函数有输入参数,s1和s2。s1是要输出的错误语句,s2是perror(s2);里的输入参数。
4、虚拟机连不上网:
我的虚拟机突然连不上网了,重启也没用……我的电脑是联网正常的。
解决方法:还原虚拟机网络设置,步骤:选择编辑选项卡的虚拟网络编辑器选项,点击页面左下角的恢复默认设置按钮。(此步骤需要在虚拟机没有运行的时候操作)
总结与感悟:
在对大家第十周学习过程中遇到的问题进行总结的过程中,我也发现了自己其实当时也有一些没有理解透彻的地方,希望自己以后学习的时候不仅要能抓住重点,还要抓住知识中的细节。这次总结让我学习到了一些新的知识,也对学过的东西再次复习巩固,这既是总结的过程,也是重新学习的过程。希望这篇总结博客能带给大家学习上的便利。