C语言查缺补漏

时间:2022-11-14 06:22:42

34、c 语言配置文件导入

1、inih-r43

2、https://blog.csdn.net/wang_xya/article/details/33733257

33、指针里的*符号是要靠近变量类型还是要靠近变量名称?

https://blog.csdn.net/zhanshen112/article/details/80722762

32、log

/*
* @file log.h
* @auther Akagi201
*
* @date 2014/09/16
*/ #ifndef LOG_H_
#define LOG_H_ (1) #ifdef NODEBUG
#define LOG(fmt, ...) do {} while (0)
#else
#define LOG(fmt, ...) fprintf(stdout, "[DEBUG] %s:%s:%d: " fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif #endif // LOG_H_
#include <stdio.h>
#include <time.h> const char* uatime()
{
struct timeval tv;
static char buf[]; memset(buf, , sizeof(buf)); // clock time
if (gettimeofday(&tv, NULL) == -) {
return buf;
} // to calendar time
struct tm* tm;
if ((tm = localtime((const time_t*)&tv.tv_sec)) == NULL) {
return buf;
} snprintf(buf, sizeof(buf),
"%d-%02d-%02d %02d:%02d:%02d.%03d",
+ tm->tm_year, + tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
(int)(tv.tv_usec / )); buf[sizeof(buf) - ] = ; return buf;
} #ifdef UA_DISABLE_LOG
#define ualog1(msg, ...) (void)0
#else
#define ualog1(msg, ...) printf("[%s] ", uatime());printf(msg, ##__VA_ARGS__);printf("\n")
#endif #define ualog(a,b...) fprintf(stderr,b);fprintf(stderr,"\n>")
#define uaslog(a,b...) printf("[%s]", uatime());fprintf(stderr,b);fprintf(stderr,"\n>")

31、C++ int与string的相互转换(含源码实现)

30、回调函数

/**
* Sound stream operations.
*/
typedef struct pjmedia_aud_stream_op
{
/**
* See #pjmedia_aud_stream_get_param()
*/
pj_status_t (*get_param)(pjmedia_aud_stream *strm,
pjmedia_aud_param *param); /**
* See #pjmedia_aud_stream_get_cap()
*/
pj_status_t (*get_cap)(pjmedia_aud_stream *strm,
pjmedia_aud_dev_cap cap,
void *value); /**
* See #pjmedia_aud_stream_set_cap()
*/
pj_status_t (*set_cap)(pjmedia_aud_stream *strm,
pjmedia_aud_dev_cap cap,
const void *value); /**
* See #pjmedia_aud_stream_start()
*/
pj_status_t (*start)(pjmedia_aud_stream *strm); /**
* See #pjmedia_aud_stream_stop().
*/
pj_status_t (*stop)(pjmedia_aud_stream *strm); /**
* See #pjmedia_aud_stream_destroy().
*/
pj_status_t (*destroy)(pjmedia_aud_stream *strm); } pjmedia_aud_stream_op;
static pjmedia_aud_stream_op alsa_stream_op =
{
&alsa_stream_get_param,
&alsa_stream_get_cap,
&alsa_stream_set_cap,
&alsa_stream_start,
&alsa_stream_stop,
&alsa_stream_destroy
};

回调函数_结构体

https://blog.csdn.net/u010333084/article/details/51339469

回调函数_注册

https://blog.csdn.net/u010333084/article/details/51406405

回调函数_数组

https://blog.csdn.net/u010333084/article/details/51381352

29、c语言查找/创建进程

#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<limits.h> #define BUFSZ PIPE_BUF int main(void)
{
FILE* fp;
int count;
char buf[BUFSZ];
char command[];
char *name = "pjsua-arm-unknown-linux-gnueabihf"; sprintf(command, "ps -C %s|wc -l", name ); if((fp = popen(command,"r")) == NULL)
perror("popen"); if( (fgets(buf,BUFSZ,fp))!= NULL )
{
count = atoi(buf);
if((count - ) == )
printf("%s not found\n",name);
else
printf("process : %s total is %d\n",name,(count - ));
}
pclose(fp); return ;
}

gcc -Wall -pipe -O3 -o getpid getpid.c

hello.c

#include<stdio.h> 

int main()
{
printf("hello,world");
while();
}

gcc  -o hello hello.c

28、向文件dump信息

main.c

char *path = "/data/test.txt";

remove(path);

dump_to_file(path,"hello,world");

dump.c

#include <stdio.h>
#include <string.h>

void dump_to_file(const char *path, char *str)
{
    FILE *fd = fopen(path, "a+");
    if (fd == NULL)
    {
        printf("fd is NULL and open file fail\n");
        return;
    }
    printf("fd != NULL\n");
    if (str && str[0] != 0)
    {
        fwrite(str, strlen(str), 1, fd);
        char *next = "\n";
        fwrite(next, strlen(next), 1, fd);
    }
    fclose(fd);
}

27、向文件写入各种类型数据

#include <stdio.h>
#include <stdlib.h>
int main() {
char *s="That's good news";
int i=;
FILE *fp;
fp=fopen("test.dat", "w"); /*建立一个文字文件只写*/
fputs("Your score of TOEFL is",fp); /*向所建文件写入一串字符*/
fputc(':', fp); /*向所建文件写冒号:*/
fprintf(fp, "%d/n", i); /*向所建文件写一整型数*/
fprintf(fp, "%s", s); /*向所建文件写一字符串*/
fclose(fp);
}

26、字符串分离

#include <stdio.h>
#include<string.h>
int main()
{
char str[] = "mv a.c b.c";
char *p;
char *buff;
buff=str;
p = strsep(&buff, " ");
while(p!=NULL)
{
printf("%s\n", p);
p = strsep(&buff, " ");
}
return ;
}

25、debug

#define BASIC() printf("[ %s %s() +%d ] ", __FILE__, __FUNCTION__, __LINE__ )

#define LOGI(args...) BASIC();printf(args)

#define LOGE(args...) LOGI(args)

24、socket http文件下载器c语言实现 ,带进度条

https://blog.csdn.net/xiongyangg/article/details/50767482

https://blog.csdn.net/qq_31629063/article/details/80846673

https://www.cnblogs.com/wainiwann/p/3148884.html

 
23、ERROR模块
/* $Id: errno.c 4613 2013-10-08 09:08:13Z bennylp $ */
/*
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <pjsip-simple/errno.h>
#include <pj/string.h> /* PJSIP-SIMPLE's own error codes/messages
* MUST KEEP THIS ARRAY SORTED!!
* Message must be limited to 64 chars!
*/ #if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0) static const struct
{
int code;
const char *msg;
} err_str[] =
{
/* Event errors */
{ PJSIP_SIMPLE_ENOPKG, "No SIP event package with the specified name" },
{ PJSIP_SIMPLE_EPKGEXISTS, "SIP event package already exist" }, /* Presence errors */
{ PJSIP_SIMPLE_ENOTSUBSCRIBE, "Expecting SUBSCRIBE request" },
{ PJSIP_SIMPLE_ENOPRESENCE, "No presence associated with the subscription" },
{ PJSIP_SIMPLE_ENOPRESENCEINFO, "No presence info in the server subscription" },
{ PJSIP_SIMPLE_EBADCONTENT, "Bad Content-Type for presence" },
{ PJSIP_SIMPLE_EBADPIDF, "Bad PIDF content for presence" },
{ PJSIP_SIMPLE_EBADXPIDF, "Bad XPIDF content for presence" },
{ PJSIP_SIMPLE_EBADRPID, "Invalid or bad RPID document"}, /* isComposing errors. */
{ PJSIP_SIMPLE_EBADISCOMPOSE, "Bad isComposing indication/XML message" },
}; #endif /* PJ_HAS_ERROR_STRING */ /*
* pjsipsimple_strerror()
*/
PJ_DEF(pj_str_t) pjsipsimple_strerror( pj_status_t statcode,
char *buf, pj_size_t bufsize )
{
pj_str_t errstr; #if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0) if (statcode >= PJSIP_SIMPLE_ERRNO_START &&
statcode < PJSIP_SIMPLE_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
{
/* Find the error in the table.
* Use binary search!
*/
int first = ;
int n = PJ_ARRAY_SIZE(err_str); while (n > ) {
int half = n/;
int mid = first + half; if (err_str[mid].code < statcode) {
first = mid+;
n -= (half+);
} else if (err_str[mid].code > statcode) {
n = half;
} else {
first = mid;
break;
}
} if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
pj_str_t msg; msg.ptr = (char*)err_str[first].msg;
msg.slen = pj_ansi_strlen(err_str[first].msg); errstr.ptr = buf;
pj_strncpy_with_null(&errstr, &msg, bufsize);
return errstr; }
} #endif /* PJ_HAS_ERROR_STRING */ /* Error not found. */
errstr.ptr = buf;
errstr.slen = pj_ansi_snprintf(buf, bufsize,
"Unknown pjsip-simple error %d",
statcode);
if (errstr.slen < || errstr.slen >= (pj_ssize_t)bufsize)
errstr.slen = bufsize - ;
return errstr;
}
22、指针作为返回值的坑
/*
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <iostream> using namespace std; char* GetMemory()
{
char *p = new char[100];
memcpy(p,"hello,world",strlen("hello,world"));
return p;
} int main()
{
char *str = GetMemory();
cout << str << endl;
delete [] str; //防止内存泄露!
return 0;
}
*/ #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h> char* GetMemory()
{
char *p = (char *)malloc(sizeof(char)*);
memcpy(p,"hello,world \n",strlen("hello,world \n"));
//p = "hello,world \n";
return p;
} int main()
{
char *str = GetMemory();
printf(str);
free(str); //防止内存泄露!
return ;
} /*
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h> void GetMemory()
{
char p[100];
memcpy(p,"hello,world \n",strlen("hello,world \n"));
printf(p);
//return p;
} int main()
{
GetMemory();
//printf(str);
//free(str); //防止内存泄露!
return 0;
}
*/
 
21、debug背景颜色定义
# linux shell color support.
RED="\\033[31m"
GREEN="\\033[32m"
YELLOW="\\033[33m"
BLACK="\\033[0m"    
 if [ $SRS_GPERF_MC = YES ]; then
        echo -e "${YELLOW}gmc(gperf memory check) for srs are builded -- Performance may suffer${BLACK}"
    else
        echo -e "${GREEN}note: gmc(gperf memory check) for srs are not builded${BLACK}"
    fi
 
20、结构体或对象排序
https://www.cnblogs.com/-beyond/p/5902113.html

19、结构体初始化的4种方式

https://blog.csdn.net/ericbar/article/details/79567108

18、 bool

/* define our own boolean type */
typedef int qbool;
#define true ((qbool)1)
#define false ((qbool)0)

17、逐行读写字符串

#include <stdio.h>
#include <stdlib.h>
#include <string.h> void ip_config_updata(char *ip, char *port)
{
FILE * fd; fd=fopen("ip.config","w");
if(fd==NULL)
{
perror("open file");
exit();
}
if(ip!=NULL)
fputs(ip,fd);
fputc( '\n', fd );
if(port!=NULL)
fputs(port,fd);
fputc( '\n', fd ); fclose(fd);
} main()
{
ip_config_updata("hello","world"); FILE * fp;
char buf[];
int len; fp=fopen("ip.config","r");
if(fp==NULL)
{
perror("open file");
exit();
} fgets(buf,sizeof(buf),fp);
len = strlen(buf);
if((buf[len-]=='\r')||(buf[len-]=='\n'))
buf[len-] = '\0';
printf("%s %d \n",buf,len - );
fgets(buf,sizeof(buf),fp);
len = strlen(buf);
if((buf[len-]=='\r')||(buf[len-]=='\n'))
buf[len-] = '\0';
printf("%s %d \n",buf,len - ); fclose(fp);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
FILE * fp;
FILE * fd;
char buf[];
int len; fp=fopen("data1.txt","r");
if(fp==NULL)
{
perror("open file");
exit();
}
fd=fopen("data2.txt","w");
if(fd==NULL)
{
perror("open file");
exit();
} while(fgets(buf,sizeof(buf),fp)!=NULL)
{
fputs(buf,fd);
printf("%s", buf); len = strlen(buf);
buf[len-] = '\0'; /*去掉换行符*/
printf("%s %d \n",buf,len - );
} fclose(fd);
fclose(fp);
return ;
}

16、堆栈

 
15、C语言中的空字符串

对于char *str字符串,判断其为空的方法为:

if(strlen(str)==0)或者if(*str=='\0')[*p表示字符串中的第一个字符]

对于char str[9]数组,判断其为空的方法为:

if(strlen(str)==0)或者if(str[0]=='\0')

14、c++11的新特性总结
 
13、getopt_long函数被用来解析命令行选项参数, 参考bluez开源项目
1)百度百科里的实例
#include <stdio.h>
#include <getopt.h>
char *l_opt_arg;
char* const short_options = "nbl:";
struct option long_options[] = {
{ "name", , NULL, 'n' },
{ "bf_name", , NULL, 'b' },
{ "love", , NULL, 'l' },
{ , , , },
};
int main(int argc, char *argv[])
{
int c;
while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -)
{
switch (c)
{
case 'n':
printf("My name is XL.\n");
break;
case 'b':
printf("His name is ST.\n");
break;
case 'l':
l_opt_arg = optarg;
printf("Our love is %s!\n", l_opt_arg);
break;
}
}
return ;
}
[root@localhost wyp]# gcc -o getopt getopt.c
[root@localhost wyp]# ./getopt -n -b -l forever
My name is XL.
His name is ST.
Our love is forever!

2)Sdptool.c中的应用

static struct {
char *cmd;
int (*func)(int argc, char **argv);
char *doc;
} command[] = {
{ "search", cmd_search, "Search for a service" },
{ "browse", cmd_browse, "Browse all available services" },
{ "records", cmd_records, "Request all records" },
{ "add", cmd_add, "Add local service" },
{ "del", cmd_del, "Delete local service" },
{ "get", cmd_get, "Get local service" },
{ "setattr", cmd_setattr, "Set/Add attribute to a SDP record" },
{ "setseq", cmd_setseq, "Set/Add attribute sequence to a SDP record" },
{ , , }
}; static void usage(void)
{
int i, pos = ; printf("sdptool - SDP tool v%s\n", VERSION);
printf("Usage:\n"
"\tsdptool [options] <command> [command parameters]\n");
printf("Options:\n"
"\t-h\t\tDisplay help\n"
"\t-i\t\tSpecify source interface\n"); printf("Commands:\n");
for (i = ; command[i].cmd; i++)
printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc); printf("\nServices:\n\t");
for (i = ; service[i].name; i++) {
printf("%s ", service[i].name);
pos += strlen(service[i].name) + ;
if (pos > ) {
printf("\n\t");
pos = ;
}
}
printf("\n");
} static struct option main_options[] = {
{ "help", , , 'h' },
{ "device", , , 'i' },
{ , , , }
}; int main(int argc, char *argv[])
{
int i, opt; bacpy(&interface, BDADDR_ANY); while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -) {
switch(opt) {
case 'i':
if (!strncmp(optarg, "hci", ))
hci_devba(atoi(optarg + ), &interface);
else
str2ba(optarg, &interface);
break; case 'h':
usage();
exit(); default:
exit();
}
} argc -= optind;
argv += optind;
optind = ; if (argc < ) {
usage();
exit();
} for (i = ; command[i].cmd; i++)
if (strncmp(command[i].cmd, argv[], ) == )
return command[i].func(argc, argv); return ;
}

fgets函数被用来命令行交互, 参考pjsip开源项目

static pj_bool_t simple_input(const char *title, char *buf, pj_size_t len)
{
char *p; printf("%s (empty to cancel): ", title); fflush(stdout);
if (fgets(buf, (int)len, stdin) == NULL)
return PJ_FALSE; /* Remove trailing newlines. */
for (p=buf; ; ++p) {
if (*p=='\r' || *p=='\n') *p='\0';
else if (!*p) break;
} if (!*buf)
return PJ_FALSE; return PJ_TRUE;
}
static void ui_answer_call()
{
pjsua_call_info call_info;
char buf[];
pjsua_msg_data msg_data_; if (current_call != -) {
pjsua_call_get_info(current_call, &call_info);
} else {
/* Make compiler happy */
call_info.role = PJSIP_ROLE_UAC;
call_info.state = PJSIP_INV_STATE_DISCONNECTED;
} if (current_call == - ||
call_info.role != PJSIP_ROLE_UAS ||
call_info.state >= PJSIP_INV_STATE_CONNECTING)
{
puts("No pending incoming call");
fflush(stdout);
return; } else {
int st_code;
char contact[];
pj_str_t hname = { "Contact", };
pj_str_t hvalue;
pjsip_generic_string_hdr hcontact; if (!simple_input("Answer with code (100-699)", buf, sizeof(buf)))
return; st_code = my_atoi(buf);
if (st_code < )
return; pjsua_msg_data_init(&msg_data_); if (st_code/ == ) {
if (!simple_input("Enter URL to be put in Contact",
contact, sizeof(contact)))
return;
hvalue = pj_str(contact);
pjsip_generic_string_hdr_init2(&hcontact, &hname, &hvalue); pj_list_push_back(&msg_data_.hdr_list, &hcontact);
} /*
* Must check again!
* Call may have been disconnected while we're waiting for
* keyboard input.
*/
if (current_call == -) {
puts("Call has been disconnected");
fflush(stdout);
return;
} pjsua_call_answer2(current_call, &call_opt, st_code, NULL, &msg_data_);
}
}
 
12、二级指针的应用
1)改变指针的值
#include <stdio.h>
#include <stdlib.h> int main()
{
int i = ;
int* p = &i; *p = 0xb;
//用指针改变一个变量的值
printf("i=0x%x\n",i);
printf("p=0x%x\n",p); int** q = &p; **q = 0xc; //用二级指针改变一个变量的值
printf("i=0x%x\n",i);
printf("p=0x%x\n",p); *q = (int *)0xFFFFFFFF;
//用二级指针改变一个指针的值
printf("i=0x%x\n",i);
printf("p=0x%x\n",p); return ;
}

2)用函数来改变指针的值

# include <stdio.h>
void f(int ** q);
int main(void)
{
int i = ;
int * p = &i;
printf("p=0x%x\n", p);
f(&p);
printf("p=0x%x\n", p); return ;
}
void f(int ** q)
{
*q = (int *)0xFFFFFFFF;
}
11、CRC
#include "stdio.h"
#include "stdint.h" uint16_t CRC_calc(uint8_t *start, uint8_t *end)
{
uint16_t crc = 0x0;
uint8_t *data; for (data = start; data < end; data++)
{
crc = (crc >> ) | (crc << );
crc ^= *data;
crc ^= (crc & 0xff) >> ;
crc ^= crc << ;
crc ^= (crc & 0xff) << ;
}
return crc;
} //计算CRC的地址从start--->end+1
int main(void)
{
uint8_t a[]={0x00,0x06,0x00,0x00,0x00,0xa0,0x00};
uint8_t c[]={0x2b,0x06,0x00,0x00,0x00,0xa0,0x00}; uint16_t b=CRC_calc(&a[],&a[]);
//uint16_t b=CRC_calc(&c[0],&c[6]); printf("b=0x%x\r\n",b); }
10、清除数组为0的项
#include <stdio.h>
#include <stdint.h> uint8_t a[]={,,,,,,,,,}; static uint8_t delete_zero_item(uint8_t data[] , uint8_t n)
{
uint8_t i = , j, len = n;
while (i < len){
if( (data[i] == ) ){
for (j = i; j < len; j++){
data[j] = data[j + ];
}
len--;
}
else
i++;
} return len;
} int main(void)
{
uint8_t k=delete_zero_item(a,); printf("%d\n",k); for(int i=;i<k;i++) printf("%d",a[i]); }
9、简易abs函数功能实现(求无符号整形表达式的绝对值)
无符号整形数据的差值,不能用if来判断,加一个常数截在一个区间。
#include "stdio.h"
#include "stdint.h" #define ABS(x) (x>0?x:-(x)) int main()
{
uint32_t utc_time_tmp = ;
uint32_t utc_time_r = ; if(utc_time_tmp - utc_time_r + > )
//也是够了
  //if(ABS(utc_time_tmp - utc_time_r)>5)
  //也是够了
//if(((utc_time_tmp > utc_time_r) && (utc_time_tmp - utc_time_r > 5))||
// ((utc_time_tmp < utc_time_r) && (utc_time_r - utc_time_tmp > 5))
//)
printf("in\r\n");
else printf("out\r\n"); return ;
}

8、在字符串中截取字符/字符串(GPS NMEA协议解析)

#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include <stdio.h> int main(){
char* str = "123,456,789,0123456,123456,0,09,10";
char sub[];
int count = , index = ;
for (index = ; index < strlen(str); ++index){
if (str[index] == ',')
++count;
if (count == )
break;
}
strncpy(sub, &str[index+], ); sub[] = '\0';
printf(sub); //123,456,789 int n = atoi(sub);
printf("string = %s integer = %d\n", sub, n); }

7、sqrt的实现

#include <stdio.h>
#ifdef CONFIG_64BIT
#define BITS_PER_LONG 64
#else
#define BITS_PER_LONG 32
#endif
/**
* int_sqrt - rough approximation to sqrt
* @x: integer of which to calculate the sqrt
*
* A very rough approximation to the sqrt() function.
*/
unsigned long int_sqrt(unsigned long x)
{
unsigned long op, res, one;
op = x;
res = ;
one = 1UL << (BITS_PER_LONG - );
while (one > op)
one >>= ; while (one != ) {
if (op >= res + one) {
op = op - (res + one);
res = res + * one;
}
res /= ;
one /= ;
}
return res;
} int main(void)
{
printf("%d\n",int_sqrt()) ;
return ;
}

6、数据转换(hex - char - byte array - acsii)

网上的整理过来的,来源记不清了,感谢作者。

DataConvert.c

#include <stdio.h>
#include <string.h>
#include "DataConvert.h" int strToHex(char *ch, char *hex)
{
int high,low;
int tmp = ;
if(ch == NULL || hex == NULL){
return -;
} if(strlen(ch) == ){
return -;
} while(*ch){
tmp = (int)*ch;
high = tmp >> ;
low = tmp & ;
*hex++ = valueToHexCh(high); //先写高字节
*hex++ = valueToHexCh(low); //其次写低字节
ch++;
}
*hex = '\0';
return ;
} int hexToStr(char *hex, char *ch)
{
int high,low;
int tmp = ;
if(hex == NULL || ch == NULL){
return -;
} if(strlen(hex) % == ){
return -;
} while(*hex){
high = hexCharToValue(*hex);
if(high < ){
*ch = '\0';
return -;
}
hex++; //指针移动到下一个字符上
low = hexCharToValue(*hex);
if(low < ){
*ch = '\0';
return -;
}
tmp = (high << ) + low;
*ch++ = (char)tmp;
hex++;
}
*ch = '\0';
return ;
} int hexCharToValue(const char ch){
int result = ;
//获取16进制的高字节位数据
if(ch >= '' && ch <= ''){
result = (int)(ch - '');
}
else if(ch >= 'a' && ch <= 'z'){
result = (int)(ch - 'a') + ;
}
else if(ch >= 'A' && ch <= 'Z'){
result = (int)(ch - 'A') + ;
}
else{
result = -;
}
return result;
} char valueToHexCh(const int value)
{
char result = '\0';
if(value >= && value <= ){
result = (char)(value + ); //48为ascii编码的‘0’字符编码值
}
else if(value >= && value <= ){
result = (char)(value - + ); //减去10则找出其在16进制的偏移量,65为ascii的'A'的字符编码值
}
else{
;
} return result;
} int hexChartoByte(char *s,char *byte)
{
int i,n = ;
for(i = ; s[i]; i += )
{
if(s[i] >= 'A' && s[i] <= 'F')
byte[n] = s[i] - 'A' + ;
else byte[n] = s[i] - '';
if(s[i + ] >= 'A' && s[i + ] <= 'F')
byte[n] = (byte[n] << ) | (s[i + ] - 'A' + );
else byte[n] = (byte[n] << ) | (s[i + ] - '');
++n;
}
return n;
} unsigned char ChartoAscii(const unsigned char cha)
{
unsigned char ascii;
if ((cha >= 0x0A) && (cha <= 0x0F))
{
ascii = cha + 'A' - ;
}
else
{
ascii = cha + '';
}
return ascii;
}

DataConvert.h

#ifndef __DATA_H
#define __DATA_H int strToHex(char *ch, char *hex);
int hexToStr(char *hex, char *ch);
int hexCharToValue(const char ch);
char valueToHexCh(const int value);
int hexChartoByte(char *s,char *byte);
unsigned char ChartoAscii(const unsigned char cha);
#endif

main.c

#include <stdio.h>
#include <string.h>
#include "DataConvert.h" #define MCU_FIRWARE_VERSION "V1.0.0"
#define BLE_FIRWARE_VERSION "V1.0.0"
#define FONT_VERSION "V1.0.0" int main(int argc, char *argv[])
{
int i;
char result[];
char *p_result = result; //转换版本号数据
char mcu_version_hex[];
char mcu_version_byte[];
char *p_ch = MCU_FIRWARE_VERSION;
char *p_hex = mcu_version_hex;
strToHex(p_ch,p_hex);
int n = hexChartoByte(mcu_version_hex,mcu_version_byte); char ble_version_hex[];
char ble_version_byte[];
p_ch = BLE_FIRWARE_VERSION;
p_hex = ble_version_hex;
strToHex(p_ch,p_hex);
int m = hexChartoByte(ble_version_hex,ble_version_byte); char font_version_hex[];
char font_version_byte[];
p_ch = FONT_VERSION;
p_hex = font_version_hex;
strToHex(p_ch,p_hex);
int k = hexChartoByte(font_version_hex,font_version_byte); //填充版本号数据
for(int i = ;i<n;i++)
printf ("%X ",0XFF & mcu_version_byte[i]); for(int i = ;i<m;i++)
printf ("%X ",0XFF & ble_version_byte[i]); for(int i = ;i<k;i++)
printf ("%X ",0XFF & font_version_byte[i]); hexToStr(p_hex, p_result);
printf("the string is:%s\n", p_result);
}

以上demo将字符串转换成utf8的字节流,可用utf8的转换工具(LoveString)还原成字符串验证。

5、union与数据的拆分与合并以及大小端的判断

1) 将int型的i拆分成4字节char型的c


#include<stdio.h>
union var{
char c[4];
int i;
}; int main(){
union var data;
data.i = 0x11020304;
printf("%x\n",data.c[0]);
printf("%x\n",data.c[1]);
printf("%x\n",data.c[2]);
     printf("%x\n",data.c[3]);
     return 0;
}

2) 合并就是反过来

#include<stdio.h>
union var{
char c[];
int i;
}; int main(){
union var data;
data.c[] = 0x04;
data.c[] = 0x03;
data.c[] = 0x02;
data.c[] = 0x11;
printf("%x\n",data.i);
     return 0;
}

3) 大小端的判断

#include<stdio.h>
union var{
char c[];
int i;
}; int main(){
union var data;
data.i = 0x11020304;
printf("%x\n",data.c[]);
printf("%x\n",data.c[]);
printf("%x\n",data.c[]);
     printf("%x\n",data.c[]); if( data.c[] == 0x11 )
{
printf("Systerm is BigEndian");
}
     return ;
}

4、连接符#的应用

1) 连接数值类型用双#

#include <stdio.h>

#define   COMB(a,b,c)   a##b##c

void main()
{
printf("%d\n",COMB(,,));
}

2) 连接字符类型用单#

#include <stdio.h>

#define   CATSTR(n)   "abcd"#n  

void main()
{
printf("%s\n",CATSTR());
}

3、linux静态库和动态库的应用

https://blog.csdn.net/m0_38087936/article/details/81262181

2、函数指针(数组)的应用以及参数传递

//预存的APP响应
void (*CmdCallbackArray[APP_CMD_MAX])(uint8_t *para) = {
,
FirewareManageCallback , // FirewareManage = 1
DataSyncCallback ,
SetCmdCallback,
HintCmdCallback,
,
BindCallback,
FactoryTestCallback,
LogCtrlCallback }; bool App_Data_L1_DataParse( uint8_t *L1_Packet,uint8_t *L1_Payload){
bool ret=true; uint8_t para[] = {};
uint16_t L2_len = ;
uint16_t check_sum = ;
L2_len =((((uint16_t)L1_Packet[])<<)|((uint16_t)L1_Packet[])); check_sum = CRC_calc(&L1_Packet[] , &L1_Packet[+L2_len]); if( ( (((uint16_t)L1_Packet[])<<)|((uint16_t)L1_Packet[]) ) == check_sum )
{
//正常接收,进入L2_Command_Content
para[] = L1_Packet[];
memcpy(&para[],&L1_Packet[],L2_len-);
CmdCallbackArray[L1_Packet[]](para);
}
return ret;
}

1、结构体指针的嵌套

工作多年,C语言基础还是不扎实,惭愧!

eg.

a.简单实例

#include<stdlib.h>
#include<stdio.h>
#include<stdint.h> int main()
{
uint8_t test[]={}; struct b_t {
uint8_t *data;
}; struct a_t {
struct b_t *b;
}; struct a_t *a = (struct a_t*)malloc(sizeof(struct a_t));
a->b = (struct b_t*)malloc(sizeof(struct b_t));
a->b->data = malloc(*sizeof(uint8_t));
a->b->data = test;
printf("%d\r\n",*(a->b->data));
return ;
}

b.一个具体的的应用,某beacon的蓝牙广播封包

#include<stdlib.h>
#include<stdio.h>
#include<stdint.h> struct event_t {
uint16_t id;
uint8_t data_len;
uint8_t *data;
};
struct manufacturer_data_t{
uint8_t data_len;
uint8_t *data;
};
struct manufacturer_title_data_t{
uint8_t data_len;
uint8_t *data;
};
struct x_beacon_t {
uint8_t length;
uint8_t bt_sig_type;
uint16_t x_service_uuid;
uint16_t frame_control;
uint16_t product_id;
uint32_t frame_counter;
uint8_t mac_add;
uint8_t capability;
struct event_t *event;
struct manufacturer_data_t *manufacturer_data;
struct manufacturer_title_data_t *manufacturer_title_data;
}*x_beacon; int main(void)
{
uint8_t test[]={}; x_beacon = (struct x_beacon_t *)malloc(sizeof(struct x_beacon_t));
x_beacon->event = (struct event_t*)malloc(sizeof(struct event_t));
x_beacon->event->data = (uint8_t*)malloc(*sizeof(uint8_t));
x_beacon->event->data = test;
x_beacon->manufacturer_data = (struct manufacturer_data_t*)malloc(sizeof(struct manufacturer_data_t)); x_beacon->manufacturer_title_data = (struct manufacturer_title_data_t*)malloc(sizeof(struct manufacturer_title_data_t)); x_beacon->length = 0x09;
x_beacon->bt_sig_type = 0x16;
x_beacon->x_service_uuid = 0xfe95;
x_beacon->frame_control = 0x1021;
x_beacon->product_id = 0x0157;
x_beacon->frame_counter = 0x00;
x_beacon->capability = 0x09; printf("%0x\r\n",x_beacon->x_service_uuid);
printf("%0d\r\n",*(x_beacon->event->data)); return ;
}

0、C语言结构体初始化的四种方法 

https://blog.csdn.net/ericbar/article/details/79567108

结构体等效

struct msg_t{
    long type;
    char buf[100];
};

struct msg_t msg;

初始化

struct msg_t msg={1,"login"};

typedef struct {
    long type;
    char buf[100];
}msg_t;

msg_t msg;

初始化

msg_t msg={1,"login"};

等效