分享几个实用的代码片段(第二弹)

大家好,我是杂烩君。

本次我们再来分享几个实用的代码小片段。

快速获取结构体成员大小及偏移量

获取结构体成员大小及偏移量的方式有多种。最简便的方式:

代码:

#include    // 获取结构体成员大小#define  GET_MEMBER_SIZE(type, member)   sizeof(((type*)0)->member)// 获取结构体成员偏移量#define  GET_MEMBER_OFFSET(type, member)  ((size_t)(&(((type*)0)->member)))typedef struct _test_struct0{    char x;      char y;     char z;}test_struct0;typedef struct _test_struct1{    char a;      char c;     short b;             int d;    test_struct0 e;}test_struct1;int main(int arc, char *argv[]){    printf("GET_MEMBER_SIZE(test_struct1, a) = %ld
", GET_MEMBER_SIZE(test_struct1, a));    printf("GET_MEMBER_SIZE(test_struct1, c) = %ld
", GET_MEMBER_SIZE(test_struct1, c));    printf("GET_MEMBER_SIZE(test_struct1, b) = %ld
", GET_MEMBER_SIZE(test_struct1, b));    printf("GET_MEMBER_SIZE(test_struct1, d) = %ld
", GET_MEMBER_SIZE(test_struct1, d));    printf("GET_MEMBER_SIZE(test_struct1, e) = %ld
", GET_MEMBER_SIZE(test_struct1, e));    printf("test_struct1 size = %ld
", sizeof(test_struct1));    printf("GET_MEMBER_OFFSET(a): %ld
", GET_MEMBER_OFFSET(test_struct1, a));    printf("GET_MEMBER_OFFSET(c): %ld
", GET_MEMBER_OFFSET(test_struct1, c));    printf("GET_MEMBER_OFFSET(b): %ld
", GET_MEMBER_OFFSET(test_struct1, b));    printf("GET_MEMBER_OFFSET(d): %ld
", GET_MEMBER_OFFSET(test_struct1, d));    printf("GET_MEMBER_OFFSET(e): %ld
", GET_MEMBER_OFFSET(test_struct1, e));    return 0;}

运行结果:

文件操作

文件操作平时用得很多,为了方便使用,可以自己根据实际需要再封装一层:

代码:

// 微信公众号:嵌入式大杂烩#include    static int file_opt_write(const char *filename, void *ptr, int size){       FILE *fp;    size_t num;    fp = fopen(filename, "wb");    if(NULL == fp)    {        printf("open %s file error!
", filename);        return -1;       }        num = fwrite(ptr, 1, size, fp);    if(num != size)    {        fclose(fp);        printf("write %s file error!
", filename);        return -1;    }     fclose(fp);    return num;}static int file_opt_read(const char *filename, void *ptr, int size){    FILE *fp;    size_t num;    fp = fopen(filename, "rb");    if(NULL == fp)    {        printf("open %s file error!
", filename);        return -1;    }        num = fread(ptr, 1, size, fp);    if(num != size)    {        fclose(fp);        printf("write %s file error!
", filename);                return -1;    }     fclose(fp);    return num;}typedef struct _test_struct{    char a;      char c;     short b;             int d;}test_struct;int main(int arc, char *argv[]){    #define FILE_NAME  "./test_file"    test_struct write_data = {0};    write_data.a = 1;    write_data.b = 2;    write_data.c = 3;    write_data.d = 4;    printf("write_data.a = %d
", write_data.a);    printf("write_data.b = %d
", write_data.b);    printf("write_data.c = %d
", write_data.c);    printf("write_data.d = %d
", write_data.d);    file_opt_write(FILE_NAME, (test_struct*)&write_data, sizeof(test_struct));    test_struct read_data = {0};    file_opt_read(FILE_NAME, (test_struct*)&read_data, sizeof(test_struct));    printf("read_data.a = %d
", read_data.a);    printf("read_data.b = %d
", read_data.b);    printf("read_data.c = %d
", read_data.c);    printf("read_data.d = %d
", read_data.d);    return 0;}

运行结果:

进度条

有时候,加上进度条可以比较方便知道当前的下载进度、写入文件的进度等。

代码:

// 微信公众号:嵌入式大杂烩#include     #include     #include     typedef struct _progress{    int cur_size;    int sum_size;}progress_t;void progress_bar(progress_t *progress_data){        int percentage = 0;    int cnt = 0;    char proc[102];    memset(proc, '\0', sizeof(proc));    percentage = (int)(progress_data->cur_size * 100 / progress_data->sum_size);    printf("percentage = %d %%
", percentage);    if (percentage <= 100)    {          while (cnt <= percentage)        {            printf("[%-100s] [%d%%]\r", proc, cnt);            fflush(stdout);              proc[cnt] = '#';              usleep(100000);            cnt++;        }    }      printf("
");}int main(int arc, char *argv[]){    progress_t progress_test = {0};    progress_test.cur_size = 65;    progress_test.sum_size = 100;    progress_bar(&progress_test);        return 0;}  

运行结果:

日志输出

日志输出常常需要带一些格式。最简单的方式如:

代码:

// 微信公众号:嵌入式大杂烩#include  #define LOG_D(fmt, args...) do\                            {\                                printf("<> ", __FILE__, __LINE__, __FUNCTION__);\                                printf(fmt, ##args);\                            }while(0)int main(int arc, char *argv[]){    char ch = 'a';    char str[10] = "ZhengN";    float float_val = 10.10;    int num = 88;    double double_val = 10.123456;    LOG_D("字符为 %c 
", ch);    LOG_D("字符串为 %s 
" , str);    LOG_D("浮点数为 %f 
", float_val);    LOG_D("整数为 %d
" , num);    LOG_D("双精度值为 %lf 
", double_val);    LOG_D("八进制值为 %o 
", num);    LOG_D("十六进制值为 %x 
", num);    return 0;}

运行结果:

可阅读往期文章:

C语言、嵌入式中几个非常实用的宏技巧

一个简单的日志模块

后台运行生成core文件

这个是我们上一篇文章分享一种你可能不知道的bug定位方法介绍的,方便大家使用,也汇总在这里。

代码:

// 微信公众号:嵌入式大杂烩#include #include #include #include #define SHELL_CMD_CONF_CORE_FILE    "echo /var/core-%e-%p-%t > /proc/sys/kernel/core_pattern"#define SHELL_CMD_DEL_CORE_FILE     "rm -f /var/core*"static int enable_core_dump(void){    int ret = -1;    int resource = RLIMIT_CORE;    struct rlimit rlim;    rlim.rlim_cur = 1 ? RLIM_INFINITY : 0;    rlim.rlim_max = 1 ? RLIM_INFINITY : 0;    system(SHELL_CMD_DEL_CORE_FILE);    if (0 != setrlimit(resource, &rlim))    {        printf("setrlimit error!
");        return -1;    }    else    {        system(SHELL_CMD_CONF_CORE_FILE);        printf("SHELL_CMD_CONF_CORE_FILE
");        return 0;    }    return ret;}int main(int argc, char **argv){    enable_core_dump();    printf("==================segmentation fault test==================
");    int *p = NULL;    *p = 1234;    return 0;}

以上就是本次分享的几个小的代码片段。

期待你的三连支持!



发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章