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

举报
嵌入式大杂烩 发表于 2022/08/17 22:38:28 2022/08/17
【摘要】 大家好,我是杂烩君。 本次我们再来分享几个实用的代码小片段。 快速获取结构体成员大小 获取结构体成员大小及偏移量的方式有多种。最简便的方式: 代码: 左右滑动查看全部代码>>> // 微信公众号:嵌入式大杂烩 #include <stdio.h>  ...

大家好,我是杂烩君。

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

快速获取结构体成员大小

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

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#include <stdio.h>   

// 获取结构体成员大小
#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\n", GET_MEMBER_SIZE(test_struct1, a));
    printf("GET_MEMBER_SIZE(test_struct1, c) = %ld\n", GET_MEMBER_SIZE(test_struct1, c));
 printf("GET_MEMBER_SIZE(test_struct1, b) = %ld\n", GET_MEMBER_SIZE(test_struct1, b));
 printf("GET_MEMBER_SIZE(test_struct1, d) = %ld\n", GET_MEMBER_SIZE(test_struct1, d));
    printf("GET_MEMBER_SIZE(test_struct1, e) = %ld\n", GET_MEMBER_SIZE(test_struct1, e));
    printf("test_struct1 size = %ld\n", sizeof(test_struct1));

 printf("GET_MEMBER_OFFSET(a): %ld\n", GET_MEMBER_OFFSET(test_struct1, a));
 printf("GET_MEMBER_OFFSET(c): %ld\n", GET_MEMBER_OFFSET(test_struct1, c));
 printf("GET_MEMBER_OFFSET(b): %ld\n", GET_MEMBER_OFFSET(test_struct1, b));
 printf("GET_MEMBER_OFFSET(d): %ld\n", GET_MEMBER_OFFSET(test_struct1, d));
 printf("GET_MEMBER_OFFSET(e): %ld\n", GET_MEMBER_OFFSET(test_struct1, e));

 return 0;
}

运行结果:

1cc9db58082973069d3c7cf1e8bbd8ff.png

文件操作

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

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#include <stdio.h>   

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!\n", filename);
        return -1;   
    }
    
    num = fwrite(ptr, 1, size, fp);
    if(num != size)
    {
        fclose(fp);
        printf("write %s file error!\n", 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!\n", filename);
        return -1;
    }
    
    num = fread(ptr, 1, size, fp);
    if(num != size)
    {
        fclose(fp);
        printf("write %s file error!\n", 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\n", write_data.a);
    printf("write_data.b = %d\n", write_data.b);
    printf("write_data.c = %d\n", write_data.c);
    printf("write_data.d = %d\n", 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\n", read_data.a);
    printf("read_data.b = %d\n", read_data.b);
    printf("read_data.c = %d\n", read_data.c);
    printf("read_data.d = %d\n", read_data.d);

 return 0;
}

运行结果:

ef766f2f34969e400b427d07894e76cf.png

进度条

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

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#include <stdio.h>    
#include <string.h>    
#include <unistd.h>    

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 %%\n", percentage);

    if (percentage <= 100)
    {  
        while (cnt <= percentage)
        {
            printf("[%-100s] [%d%%]\r", proc, cnt);
            fflush(stdout);  
            proc[cnt] = '#';  
            usleep(100000);
            cnt++;
        }

    }  
    printf("\n");
}

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;
}

运行结果:

76969d1a9466a283633f438058e15fa5.png d3cf5b22e51c1ee30ae0839fb70276f7.gif

日志输出

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

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#include <stdio.h> 

#define LOG_D(fmt, args...) do\
                            {\
                                printf("<<File:%s  Line:%d  Function:%s>> ", __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 \n", ch);
    LOG_D("字符串为 %s \n" , str);
    LOG_D("浮点数为 %f \n", float_val);
    LOG_D("整数为 %d\n" , num);
    LOG_D("双精度值为 %lf \n", double_val);
    LOG_D("八进制值为 %o \n", num);
    LOG_D("十六进制值为 %x \n", num);

 return 0;
}

运行结果:

c2e7a5cd4677021d5ba79ee62c86192f.png

可阅读往期文章:

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

一个简单的日志模块

后台运行生成core文件

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

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>

#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!\n");
        return -1;
    }
    else
    {
        system(SHELL_CMD_CONF_CORE_FILE);
        printf("SHELL_CMD_CONF_CORE_FILE\n");
        return 0;
    }

    return ret;
}

int main(int argc, char **argv)
{
    enable_core_dump();

    printf("==================segmentation fault test==================\n");

    int *p = NULL;
    *p = 1234;

    return 0;
}

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

期待你的三连支持!

注意

由于微信公众号近期改变了推送规则,如果您想经常看到我们的文章,可以在每次阅读后,在页面下方点一个「赞」或「在看」,这样每次推送的文章才会第一时间出现在您的订阅列表里。

猜你喜欢:

分享一种你可能不知道的bug定位方法

分享一种修改配置文件的方法

《嵌入式大杂烩周记第 13 期:lz4》

《嵌入式并行多线程处理器,了解一下!》

《分享一种修改配置文件的方法》

《分享几个实用的代码片段(附代码例子)》

《废旧板子再利用:搭建无线调试环境!》

《嵌入式段错误的3种调试方法汇总!》

《简说TCP通信非阻塞接收(附代码例子)》

《TCP server如何与多个client通信?》

《TCP通信常用接口的使用封装》

《写国际化的嵌入式代码,时间问题如何处理?》

《Linux命令行万能解压命令》

《嵌入式软件中,总线错误的坑?替大家先踩一步》

《分享嵌入式软件调试方法及几个有用的工具!》

《分享两点提高编程能力的建议!》

《嵌入式开发中常见3个的C语言技巧》

《分享几个嵌入式 C 中的实用技巧》

在公众号聊天界面回复1024,可获取嵌入式资源;回复 m ,可查看文章汇总

文章来源: blog.csdn.net,作者:嵌入式大杂烩,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/zhengnianli/article/details/126357782

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。