yolo源码(三)关于读取txt文件构建到数据结构里

yolo是c语言写的,并且读取图像数据是根据txt文件读取的,这次主要记录一下
    list *plist = get_paths(train_images);
    //int N = plist->size;
    char **paths = (char **)list_to_array(plist);

主要介绍这两个函数的由来以及相关介绍.里面有的解释不清楚以及出错的地方欢迎指正.

#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h> 
#include <stddef.h>
typedef struct node{
    void *val;//指针,目的是指向每一行的头一个指针位置,用来存字符串的,*val指的是字符串的首地址
    struct node *next;//这边可以理解成一个链表,*next指向链表的下一端
    struct node *prev;//*prev指向链表的上一端
} node;


typedef struct list{
    int size; //这边是指图片的数量,
    node *front;//可以理解成最简单的二叉树,深度为2,只有front和back两个孩子,front里面又是一个node结构体,我们可以看node结构体
    node *back;
} list;


void **list_to_array(list *l)
{
    void **a = calloc(l->size, sizeof(void*));
    int count = 0;
    node *n = l->front;/*结构体,指针地址指向l->front,此时的n就是l->front里面的内容*/
    // node *n = l->back;/*这边我不怎么想得通,为什么是front,而不是back.我认为了l->back才是这个数据结构
    //当然,我的想法是错的,只是没看懂这个数据结构*/
    while(n){
        a[count++] = n->val;//这个while循环就是将链表n中的所有字符串赋值给a[]
        n = n->next;//继续链表n的下一个
    }
    return a;
}

list *make_list()
{
	list *l = malloc(sizeof(list));//在c语言中结构体不可以再定义结构体变量,但是可以定义结构体指针
    //在c语言中,指针如果不开辟空间,是不能直接使用的
    // fprintf(stderr,"%d\n",sizeof(list));//返回的是24,也就是为指针l开辟一个24的空间,关于sizeof求嵌套结构体的大小
                                     //有空会简单介绍一下
	l->size = 0;
	l->front = 0;
	l->back = 0;
	return l;
}

char *fgetl(FILE *fp)
{
    if(feof(fp)) return 0;//int型,检查文件是否结束,如果结束,返回0
    size_t size = 512;
    char *line = malloc(size*sizeof(char));//开辟一个512的空间,如果图像路径超过512个字符,会出问题的,当然,谁的路径会有这么长呢?
    if(!fgets(line, size, fp)){/*从文件流读取一行送到缓冲区,每行的字符不能超过size-1.
                            当遇到换行符或者缓冲区已满,fgets就会停止,返回读到的数据*/
        free(line);//free的时候,系统会比对一下这个地址,是不是malloc申请的,如果不是,不给释放 
                    //如果是的话,系统就知道要释放多大内存,因为malloc的时候,系统有记录的。
        return 0;
    }
}

void list_insert(list *l, void *val)
{
	node *new = malloc(sizeof(node));//为新的new开辟空间,注意这个new永远都是新的
	new->val = val;//将参数val的内容赋值给new里面的val,其实这是将每一行的图像路径字符串给了val
	new->next = 0;//new的下一个为0,但是前面一个还是起作用的

	if(!l->back){//如果l-back不为空
		l->front = new;//l的front孩子 就是new这个node字符串
		new->prev = 0;//l的前一个孩子为0
	}else{//这边没怎么看懂数据结构的目的,只能浅谈一下,希望有了解的道友交流一波
		l->back->next = new;//l的back孩子的下一个为new
		new->prev = l->back;//new链表的前一个为l的back孩子,new是链表
        /*链表,给了这个表的下一个值,那也要给上一个值啊,准确的说,这个是构建l->back链表,l->back的下一个是new,而这个new的上一个是l->back*/
	}
	l->back = new;//l的back孩子是new
	++l->size;//l-size记录有多少行,也就是多少张图像
}

void file_error(char *s)
{
    fprintf(stderr, "Couldn't open file: %s\n", s);
    exit(0);
}


list *get_paths(char *filename)
{
    char *path;
    FILE *file = fopen(filename, "r");//打开文件,文件指针名=fopen(文件名,使用文件方式)
                                //“文件指针名”必须是被说明为FILE 类型的指针变量;
    if(!file) file_error(filename);
    list *lines = make_list(); 
    while((path=fgetl(file))){ //这边涉及比较复杂的数据结构,文字很难描述
        list_insert(lines, path);
    }
    fclose(file);
    return lines;
}
int main()
{
    char *train_images = "/home/hjxu/Yolo/hjxu_train_code/2007_train.txt";
    
    // char *copy = malloc(strlen(train_images)+1);
    // strncpy(copy, train_images, strlen(train_images)+1);
    // fprintf(stderr,"%s\n",copy);
    list *plist = get_paths(train_images);
    // fprintf(stderr, plist->size);
    char **paths = (char **)list_to_array(plist);//将plist里面的内容转化成数组
    int i;
    for(i=0;i<plist->size;i++)
    {
    fprintf(stderr, "%s", *(paths+i));//**paths就是这个数组的,*(paths+i)则是第i行,或者paths[i]就可以了
    }
    return 0;
}





有一点我想不通,一直数据都是放在l的back里,为什么会调用l的front,希望小伙伴能help一下

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值