C
39. fread file
while( ((i=fread(buffer,1,160,infile))>0) && (runcond) ) { rtp_session_send_with_ts(session,buffer,i,user_ts); user_ts+=160; } while(!feof(ts_file)){ int read_len = fread(buf+count, 1, TS_PACKET_SIZE, ts_file); count += read_len; }
38. Handle a signal
https://rosettacode.org/wiki/Handle_a_signal
37. 将socket设置为非阻塞(non-blocking)
正确的做法应该是使用fcntl:
int flags = fcntl(m_sock, F_GETFL, 0);
fcntl(m_sock, F_SETFL, flags|O_NONBLOCK);
https://www.cnblogs.com/zhangxuan/p/6306326.html
https://blog.csdn.net/qq_24373811/article/details/52356064
36. log
https://github.com/waynetran/log.c
https://github.com/pymumu/tinylog
35、c语言 判断ip是否合法的简单例子
https://blog.csdn.net/liupengying123/article/details/38514425
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
#ifdef NDEBUG #define LOG(fmt, ...) ((void)0) #define LOGI(fmt, ...) ((void)0) #define LOGD(fmt, ...) ((void)0) #define LOGE(fmt, ...) ((void)0) #else #define LOG(fmt, ...) do{ printf(fmt "\n", ##__VA_ARGS__); } while(0) #define LOGI(fmt, ...) do{ printf("%s: " fmt "\n", __FILENAME__, ##__VA_ARGS__); } while(0) #define LOGD(fmt, ...) do{ printf("\033[33m%s: " fmt "\033[m\n", __FILENAME__, ##__VA_ARGS__); } while(0) #define LOGE(fmt, ...) do{ printf("\033[31mERROR: %s: %s: %d: " fmt "\033[m\n", __FILENAME__, __func__, __LINE__, ##__VA_ARGS__); } while(0) #endif
#include <stdio.h> #include <time.h> const char* uatime() { struct timeval tv; static char buf[23]; memset(buf, 0, sizeof(buf)); // clock time if (gettimeofday(&tv, NULL) == -1) { 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", 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000)); buf[sizeof(buf) - 1] = 0; 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>")
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[150]; 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 - 1) == 0) printf("%s not found\n",name); else printf("process : %s total is %d\n",name,(count - 1)); } pclose(fp); return 0; }
gcc -Wall -pipe -O3 -o getpid getpid.c
hello.c
#include<stdio.h> int main() { printf("hello,world"); while(1); }
gcc -o hello hello.c
28、向文件dump信息
main.c
char *path = "/data/test.txt";
remove(path);
dump_to_file(path,"hello,world");
dump.c
int dump_bin(const char * file, char *buf, int len) { FILE *fp = fopen(file, "a+b"); if(fp) { fwrite(buf, len, 1, fp); fclose(fp); fp = NULL; return -1; } return 0; } int dump_str(const char * file, char *buf, int len) { FILE *fp = fopen(file, "a+b"); if(fp) { fprintf(fp,"%s",buf); fclose(fp); fp = NULL; return -1; } return 0; }
read file
static off_t file_size; static char* get_h264_frame(char* raw_file) { int raw_fd = open(raw_file, O_RDONLY); if (raw_fd < 0) { printf("open h264 raw file %s failed.\n", raw_file); return NULL; } file_size = lseek(raw_fd, 0, SEEK_END); if (file_size <= 0) { printf("h264 raw file %s empty.\n", raw_file); return NULL; } //printf("read entirely h264 raw file, size=%dKB \n", (int)(file_size / 1024)); char*h264_raw = (char*)malloc(file_size); if (!h264_raw) { printf("alloc raw buffer failed for file %s.\n", raw_file); return NULL; } lseek(raw_fd, 0, SEEK_SET); ssize_t nb_read = 0; if ((nb_read = read(raw_fd, h264_raw, file_size)) != file_size) { printf("buffer %s failed, expect=%dKB, actual=%dKB.\n", raw_file, (int)(file_size / 1024), (int)(nb_read / 1024)); return NULL; } close(raw_fd); return h264_raw; }
int remove(char * filename);
int ftruncate(int fildes, off_t length);
1.ftruncate清空文件后,需要使用rewind或fseek将文件指针移到文件头。
2.ftruncate第一个参数是文件描述符int,而不是文件指针FILE *
27、向文件写入各种类型数据
#include <stdio.h> #include <stdlib.h> int main() { char *s="That's good news"; int i=617; 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 0; }
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
/* $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 = 0; int n = PJ_ARRAY_SIZE(err_str); while (n > 0) { int half = n/2; int mid = first + half; if (err_str[mid].code < statcode) { first = mid+1; n -= (half+1); } 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 < 1 || errstr.slen >= (pj_ssize_t)bufsize) errstr.slen = bufsize - 1; return errstr; }
/* #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)*100); 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 0; } /* #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; } */
RED="\\033[31m"
GREEN="\\033[32m"
YELLOW="\\033[33m"
BLACK="\\033[0m"
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
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(0); } 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[1024]; int len; fp=fopen("ip.config","r"); if(fp==NULL) { perror("open file"); exit(0); } fgets(buf,sizeof(buf),fp); len = strlen(buf); if((buf[len-1]=='\r')||(buf[len-1]=='\n')) buf[len-1] = '\0'; printf("%s %d \n",buf,len - 1); fgets(buf,sizeof(buf),fp); len = strlen(buf); if((buf[len-1]=='\r')||(buf[len-1]=='\n')) buf[len-1] = '\0'; printf("%s %d \n",buf,len - 1); fclose(fp); }
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { FILE * fp; FILE * fd; char buf[1024]; int len; fp=fopen("data1.txt","r"); if(fp==NULL) { perror("open file"); exit(0); } fd=fopen("data2.txt","w"); if(fd==NULL) { perror("open file"); exit(0); } while(fgets(buf,sizeof(buf),fp)!=NULL) { fputs(buf,fd); printf("%s", buf); len = strlen(buf); buf[len-1] = '\0'; /*去掉换行符*/ printf("%s %d \n",buf,len - 1); } fclose(fd); fclose(fp); return 0; }
16、堆栈
对于char *str字符串,判断其为空的方法为:
if(strlen(str)==0)或者if(*str=='\0')[*p表示字符串中的第一个字符]
对于char str[9]数组,判断其为空的方法为:
if(strlen(str)==0)或者if(str[0]=='\0')
#include <stdio.h> #include <getopt.h> char *l_opt_arg; char* const short_options = "nbl:"; struct option long_options[] = { { "name", 0, NULL, 'n' }, { "bf_name", 0, NULL, 'b' }, { "love", 1, NULL, 'l' }, { 0, 0, 0, 0}, }; int main(int argc, char *argv[]) { int c; while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) { 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 0; } [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" }, { 0, 0, 0 } }; static void usage(void) { int i, pos = 0; 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 = 0; command[i].cmd; i++) printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc); printf("\nServices:\n\t"); for (i = 0; service[i].name; i++) { printf("%s ", service[i].name); pos += strlen(service[i].name) + 1; if (pos > 60) { printf("\n\t"); pos = 0; } } printf("\n"); } static struct option main_options[] = { { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, { 0, 0, 0, 0 } }; int main(int argc, char *argv[]) { int i, opt; bacpy(&interface, BDADDR_ANY); while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { case 'i': if (!strncmp(optarg, "hci", 3)) hci_devba(atoi(optarg + 3), &interface); else str2ba(optarg, &interface); break; case 'h': usage(); exit(0); default: exit(1); } } argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); exit(1); } for (i = 0; command[i].cmd; i++) if (strncmp(command[i].cmd, argv[0], 4) == 0) return command[i].func(argc, argv); return 1; }
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[128]; pjsua_msg_data msg_data_; if (current_call != -1) { 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 == -1 || 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[120]; pj_str_t hname = { "Contact", 7 }; 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 < 100) return; pjsua_msg_data_init(&msg_data_); if (st_code/100 == 3) { 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 == -1) { puts("Call has been disconnected"); fflush(stdout); return; } pjsua_call_answer2(current_call, &call_opt, st_code, NULL, &msg_data_); } }
#include <stdio.h> #include <stdlib.h> int main() { int i = 9; 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 0; }
2)用函数来改变指针的值
# include <stdio.h> void f(int ** q); int main(void) { int i = 9; int * p = &i; printf("p=0x%x\n", p); f(&p); printf("p=0x%x\n", p); return 0; } void f(int ** q) { *q = (int *)0xFFFFFFFF; }
#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 >> 8) | (crc << 8); crc ^= *data; crc ^= (crc & 0xff) >> 4; crc ^= crc << 12; crc ^= (crc & 0xff) << 5; } return crc; } //计算CRC的地址从start--->end+1 int main(void) { uint8_t a[7]={0x00,0x06,0x00,0x00,0x00,0xa0,0x00}; uint8_t c[7]={0x2b,0x06,0x00,0x00,0x00,0xa0,0x00}; uint16_t b=CRC_calc(&a[0],&a[6]); //uint16_t b=CRC_calc(&c[0],&c[6]); printf("b=0x%x\r\n",b); }
#include <stdio.h> #include <stdint.h> uint8_t a[10]={1,2,3,4,5,6,7,8,9,0}; static uint8_t delete_zero_item(uint8_t data[] , uint8_t n) { uint8_t i = 0, j, len = n; while (i < len){ if( (data[i] == 0) ){ for (j = i; j < len; j++){ data[j] = data[j + 1]; } len--; } else i++; } return len; } int main(void) { uint8_t k=delete_zero_item(a,10); printf("%d\n",k); for(int i=0;i<k;i++) printf("%d",a[i]); }
#include "stdio.h" #include "stdint.h" #define ABS(x) (x>0?x:-(x)) int main() { uint32_t utc_time_tmp = 11; uint32_t utc_time_r = 5; if(utc_time_tmp - utc_time_r + 5 > 10) //也是够了 //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 0; }
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[3]; int count = 0, index = 0; for (index = 0; index < strlen(str); ++index){ if (str[index] == ',') ++count; if (count == 6) break; } strncpy(sub, &str[index+1], 2); sub[2] = '\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 = 0; one = 1UL << (BITS_PER_LONG - 2); while (one > op) one >>= 2; while (one != 0) { if (op >= res + one) { op = op - (res + one); res = res + 2 * one; } res /= 2; one /= 4; } return res; } int main(void) { printf("%d\n",int_sqrt(16)) ; return 0 ; }
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 = 0; if(ch == NULL || hex == NULL){ return -1; } if(strlen(ch) == 0){ return -2; } while(*ch){ tmp = (int)*ch; high = tmp >> 4; low = tmp & 15; *hex++ = valueToHexCh(high); //先写高字节 *hex++ = valueToHexCh(low); //其次写低字节 ch++; } *hex = '\0'; return 0; } int hexToStr(char *hex, char *ch) { int high,low; int tmp = 0; if(hex == NULL || ch == NULL){ return -1; } if(strlen(hex) %2 == 1){ return -2; } while(*hex){ high = hexCharToValue(*hex); if(high < 0){ *ch = '\0'; return -3; } hex++; //指针移动到下一个字符上 low = hexCharToValue(*hex); if(low < 0){ *ch = '\0'; return -3; } tmp = (high << 4) + low; *ch++ = (char)tmp; hex++; } *ch = '\0'; return 0; } int hexCharToValue(const char ch){ int result = 0; //获取16进制的高字节位数据 if(ch >= '0' && ch <= '9'){ result = (int)(ch - '0'); } else if(ch >= 'a' && ch <= 'z'){ result = (int)(ch - 'a') + 10; } else if(ch >= 'A' && ch <= 'Z'){ result = (int)(ch - 'A') + 10; } else{ result = -1; } return result; } char valueToHexCh(const int value) { char result = '\0'; if(value >= 0 && value <= 9){ result = (char)(value + 48); //48为ascii编码的‘0’字符编码值 } else if(value >= 10 && value <= 15){ result = (char)(value - 10 + 65); //减去10则找出其在16进制的偏移量,65为ascii的'A'的字符编码值 } else{ ; } return result; } int hexChartoByte(char *s,char *byte) { int i,n = 0; for(i = 0; s[i]; i += 2) { if(s[i] >= 'A' && s[i] <= 'F') byte[n] = s[i] - 'A' + 10; else byte[n] = s[i] - '0'; if(s[i + 1] >= 'A' && s[i + 1] <= 'F') byte[n] = (byte[n] << 4) | (s[i + 1] - 'A' + 10); else byte[n] = (byte[n] << 4) | (s[i + 1] - '0'); ++n; } return n; } unsigned char ChartoAscii(const unsigned char cha) { unsigned char ascii; if ((cha >= 0x0A) && (cha <= 0x0F)) { ascii = cha + 'A' - 10; } else { ascii = cha + '0'; } 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[1024]; char *p_result = result; //转换版本号数据 char mcu_version_hex[12]; char mcu_version_byte[6]; 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[12]; char ble_version_byte[6]; 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[12]; char font_version_byte[6]; 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 = 0;i<n;i++) printf ("%X ",0XFF & mcu_version_byte[i]); for(int i = 0;i<m;i++) printf ("%X ",0XFF & ble_version_byte[i]); for(int i = 0;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[4]; int i; }; int main(){ union var data; data.c[0] = 0x04; data.c[1] = 0x03; data.c[2] = 0x02; data.c[3] = 0x11; printf("%x\n",data.i);
return 0; }
3) 大小端的判断
#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]); if( data.c[0] == 0x11 ) { printf("Systerm is BigEndian"); } return 0; }
4、连接符#的应用
1) 连接数值类型用双#
#include <stdio.h> #define COMB(a,b,c) a##b##c void main() { printf("%d\n",COMB(1,2,3)); }
2) 连接字符类型用单#
#include <stdio.h> #define CATSTR(n) "abcd"#n void main() { printf("%s\n",CATSTR(100)); }
3、linux静态库和动态库的应用
https://blog.csdn.net/m0_38087936/article/details/81262181
2、函数指针(数组)的应用以及参数传递
//预存的APP响应 void (*CmdCallbackArray[APP_CMD_MAX])(uint8_t *para) = { 0 , FirewareManageCallback , // FirewareManage = 1 DataSyncCallback , SetCmdCallback, HintCmdCallback, 0, BindCallback, FactoryTestCallback, LogCtrlCallback }; bool App_Data_L1_DataParse( uint8_t *L1_Packet,uint8_t *L1_Payload){ bool ret=true; uint8_t para[60] = {0}; uint16_t L2_len = 0; uint16_t check_sum = 0; L2_len =((((uint16_t)L1_Packet[5])<<8)|((uint16_t)L1_Packet[6])); check_sum = CRC_calc(&L1_Packet[9] , &L1_Packet[9+L2_len]); if( ( (((uint16_t)L1_Packet[7])<<8)|((uint16_t)L1_Packet[8]) ) == check_sum ) { //正常接收,进入L2_Command_Content para[0] = L1_Packet[2]; memcpy(¶[1],&L1_Packet[10],L2_len-1); CmdCallbackArray[L1_Packet[9]](para); } return ret; }
typedef struct task { pthread_t id; int fd; uint8_t buf[1024]; int size; }task_t; void (*task_array[])(int fd, uint8_t* buf, uint8_t size) = { qx_raw , qx_raw_2_ubx , qx_raw_2_ubx_zhd , zhd_raw, zhd_raw_2_ubx, zhd_raw_2_ubx_zhd, }; static void* task_done(void *arg) { task_t task = *(task_t*)(arg); int i = 0; while(task_array[i] != NULL){ (task_array[i])(task.fd, task.buf, task.size); i++; } printf ("task %d done !\n", task.fd); }
static int send_ubx2mc(int fd, unsigned char *cmd, int len);
static int send_zhd2mc(int fd, unsigned char *cmd, int len);
static void agnss_update(int fd, QX_report_data_t rp, int (*send_cmd2mc)(int, unsigned char*, int));
工作多年,C语言基础还是不扎实,惭愧!
eg.
a.简单实例
#include<stdlib.h> #include<stdio.h> #include<stdint.h> int main() { uint8_t test[8]={1}; 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(8*sizeof(uint8_t)); a->b->data = test; printf("%d\r\n",*(a->b->data)); return 0; }
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[8]={1}; 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(8*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; }
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"};
等效