getopt_long函数,能够在Linux命令行提取短选项(-开头,与选参数之间隔空)与长选项(–开头连接参数)。它的原型是这样的。
#include#include int getopt_long(int argc, char * const argv[],const char *optstring,const struct option *longopts, int *longindex);
如果只想要提取长选项,那么就需要把optstring指针设为NULL。如果也需要用到短选项,那么这里设置为标识的字符。
option结构体的原型为
struct option {
const char *name;//长选项的选项名。
int has_arg;//0:不需要参数,1:需要参数,2:参数是可选的
int *flag;//指定如何为长选项返回结果。如果flag是null,那么getopt_long返回val(可以将val设置为等效的短选项字符),否则getopt_long返回0.
int val;//返回值,参考flag
};
那么使用的时候,我们势必要判断命令行传入各个参数是否符合我们的要求,再进行筛选提取。
while( -1 != (optvar=getopt_long(argc,argv,"i:c:bHaho",opts,NULL)) )//返回值为-1说明已经解析完所有选项
optvar所声明的变量类型是至关重要的,使用int而不要用错用成char。而且,结构体的最后一行必须为全0。
优美使用宏定义为什么要用上宏定义?
通常在函数返回的时候,我们使用的是return 0、return 1等反馈执行结果给调用者,而返回值等效的结果视不同人而定。stdlib库则内部宏定义了一对EXIT_SUCCESS(0)、EXIT_FAILURE(1)。让编写者与合作者的代码更容易理解。
在进行多种条件判断时,也可以进行宏定义替换掉令人费解的多种条件,例如:返回-1为无效值、0为超时、1为取值完成、2为仍然存在,条件较多,就可以采用宏定义进行替换。
文件IO中不断增长的文件描述符fd文件描述符是什么呢?
一个进程,利用open、opendir发起系统调用,操作系统就会将打开的文件加载内存中进行管理。每个进程的PCB中都会有一个文件描述符表(struct file_struct),而打开的文件的属性(struct file)就像数组一样存放在文件描述符表中。文件描述符fd就类似于文件的属性在文件描述符表中的下标。
为什么我的文件描述符会不断增长?
操作系统会在系统调用后给我们依照按小分配原则给我们返回当前可用的最小的fd。如果发现文件描述符fd在程序运行后一直在增长,直到达到系统规定的数量(用户级为1024)抛错。这是因为我们的程序可能由于我们的疏忽,在重新打开一个文件或者文件夹后,忘记关闭该文件描述符,操作系统则不会帮我们断开我们已打开的文件描述符与文件的联系。fd则会一直增长。
什么是段错误?
段错误是我们的程序发生了越界访问,访问了不该访问的内存,这段内存可能不存在,也有可能是受系统保护、或者缺少文件、文件损坏,cpu就会产生相应的保护。linux内核会给产生段错误的程序发送SIGSEGV信号。
为什么在使用sqlite3的时候出现段错误现象?
有时候我们去调用打开数据库,想从其中提取数据,但是如果该数据库的数据表是一个空的数据表,我们是会拿到空的值。拿到这本身是没有错的,但是我们再去操作这个空的值(比如将它strcpy到一个数组),就会发生段错误。所以我们要留意数据库中的数据是否正常。
为什么同样的语句,在命令行执行可以,放进代码sqlite3_exec()里执行不行呢?
检查语句后面是否漏了分号。
关于delete用不了limit的原因
最新版本的sqlite的delete语句是不支持limit的。
daemon内部做了什么工作?
daemon函数实际上是程序运行后开了一个子进程继承父进程的资源,父进程退出;然后再执行一个setsid函数,创建会话,开启新的进程组、会话期,让它脱离原先的进程、会话期;再开一个子进程,用以重新申请打开一个控制终端,父进程退出…
daemon进程的老爹进程在daemon进程还活着的时候就死掉了,所以它就作为孤儿进程被init进程托管了。
为什么要放在daemon前面呢?
这是使用daemon(0,?)才会出现的问题。
而我们一般写程序,可能会使用到相对路径,如果将一个文件在daemon函数前open,那么就是原进程人家打开的文件,这个相对路径是相对原进程的也就是,而daemon又可以去继承。
而如果放在daemon(0,?)后面,它已经挂在根目录下面了,这时候的相对路径是根目录,但是,它可能并没有打开根目录文件的权限,所以会打开失败,再去操作可能会发生段错误。
能够在daemon前面启用线程吗?
不能,因为子进程不能够继承父进程的线程,子进程按照规定,只能有一个线程



