欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

list *sections = read_cfg(filename);

程序员文章站 2022-06-26 11:34:13
...

read_cfg函数主体

list *read_cfg(char *filename)
{
    FILE *file = fopen(filename, "r");//打开文件
    if(file == 0) file_error(filename);//若文件不存在,则显示错误,并跳出函数;
    char *line;
    int nu = 0;
    list *options = make_list();//创建list链表结点,用来存储之后的文件数据;
    section *current = 0;//这里创建了一个指向结构体section的指针,其结构体如下所示:
    /*
    typedef struct{
    				char *type;
   					list *options;//之前已详细讲过
					}section;
	*/
    while((line=fgetl(file)) != 0)//判断fgetl(file)读入的line是否为空,即line是否读入了数据
    {
        ++ nu;
        strip(line);//去除line中的空格换行和跳格符号,并在最后加上'\0';
        switch(line[0])//这里与读取data_cfg时不同,添加了一个case分支
        {
        	//这个分支会在出现了新的网络层时执行,因为在cfg文件中会以[](中括号)来分层
            case '[':
                current = malloc(sizeof(section));//为current指向的结构体分配内存
                list_insert(options, current);//之前已经讲过,这里与之前不同的是进行了指针嵌套,具体如下图所示
                current->options = make_list();//使current->options指向新建的list链表结点
                current->type = line;//使得current->type指向数组line的内存地址
                break;
            case '\0':
            case '#':
            case ';':
                free(line);
                break;
            default:
                if(!read_option(line, current->options)){//用来读取每一层网络的具体数据
                    fprintf(stderr, "Config file error line %d, could parse: %s\n", nu, line);
                    free(line);
                }
                break;
        }
    }
    fclose(file);
    return options;
}

第一次出现" [ "时,进入list_insert(options, current) 函数后:
(1)首先会声明一个指向node结构体的指针new,并动态存储分配内存;
(2)将指针current赋给new->val,使new->val指向section结构体,并将结点后向指针new->next指向设置为0,防止其指向未知内存;
(3)由于是第一次传输数据,链表结点options的后向指针l->back=0,所以会将list链表的前向指针指向新建立的node结点,l->front = new,并将new->prev = 0,因为这是首元结点;
(4)最后将l->back = new,使其方便下一个node结点连接到链表中,并经size加一。

运行完list_insert(options, current) 函数后,current指向的结构体会进行赋值处理, current->options = make_list()会令指针current->options 指向新建的list链表结点current->type = line;会令指针current->type 指向line所在的内存地址

运行如下图所示:
list *sections = read_cfg(filename);
current->type指向的内存地址中的变量如下所示,很显然,其就是存储每一层网络结构的名字

current->type = [net]
current->type = [convolutional]
current->type = [maxpool]
current->type = [convolutional]
current->type = [maxpool]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [maxpool]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [maxpool]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [convolutional]
current->type = [local]
current->type = [dropout]
current->type = [connected]
current->type = [detection]

read_cfg函数具体运行如下图所示:
list *sections = read_cfg(filename);
从图中可以看出其实就是每一个section储存了一层网络数据。