Linux下C开发使用小技巧

Linux下C开发使用小技巧

基础类

整形,字符串互转

C语言提供了几个标准库函数,可以将任意类型(整型、长整型、浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明。
● itoa():将整型值转换为字符串。
● ltoa():将长整型值转换为字符串。
● ultoa():将无符号长整型值转换为字符串。
● gcvt():将浮点型数转换为字符串,取四舍五入。
● ecvt():将双精度浮点型值转换为字符串,转换结果中不包含十进制小数点。
● fcvt():指定位数为转换精度,其余同ecvt()。

除此外,还可以使用sprintf系列函数把数字转换成字符串,其比itoa()系列函数运行速度慢

以下是用itoa()函数将整数转换为字符串的一个例子:

# include <stdio.h>
# include <stdlib.h>
void main (void)
{
int num = 100;
char str[25];
itoa(num, str, 10);
printf("The number 'num' is %d and the string 'str' is %s. \n" ,
num, str);
}

itoa()函数有3个参数:第一个参数是要转换的数字,第二个参数是要写入转换结果的目标字符串,第三个参数是转移数字时所用 的基数。在上例中,转换基数为10。10:十进制;2:二进制…

itoa并不是一个标准的C函数,它是Windows特有的,如果要写跨平台的程序,请用sprintf。是Windows平台下扩展的,标准库中有sprintf,功能比这个更强,用法跟printf类似:

char str[255];
sprintf(str, "%x", 100); //将100转为16进制表示的字符串。

cpp中string转int:

void str2int(int &int_temp,const string &string_temp)  
{  int_temp=atoi(string_temp.c_str());                     
}  

cpp中int转string:

void int2str(const int &int_temp,string &string_temp)  
{  char s[12];             //设定12位对于存储32位int值足够  itoa(int_temp,s,10);            //itoa函数亦可以实现,但是属于C中函数,在C++中推荐用流的方法  string_temp=s;  
}  

架构类

Linux C代码实现主函数参数选项解析
1. 手动解析版本

使用argc、argv,逐个字符比较,得到要想的参数名字即进行判断、解析。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>int debug;void show_version(char* name)
{printf("%s by Late Lee, version: 1.0\n", name);
}void usage(char* name)
{show_version(name);printf("         -h,  --help           short help\n");printf("         -v,  --version        show version\n");
}int main(int argc, char *argv[])
{int i = 0;/* early check for debug and config parameter */if (argc > 1) {for (i = 1; i < argc; i++){if ((strcmp(argv[i], "-D")==0) || (strcmp(argv[i], "--debug")==0)){debug = 1;}}}///* parse parameters, maybe not the best way but... */for (i = 1; i < argc; i++){if (debug)printf("arg %d: \"%s\"\n",i,argv[i]);// helpif ((strcmp(argv[i],"-h")==0) || (strcmp(argv[i],"--help")==0)){usage(argv[0]);return 0;}// versionelse if ((strcmp(argv[i],"-v")==0) || (strcmp(argv[i],"--version")==0)){show_version(argv[0]);return 0;}// debugelse if ((strcmp(argv[i],"-D")==0) || (strcmp(argv[i],"--debug")==0)){debug=1;}else if ((strcmp(argv[i],"fpga")==0)){printf("test of fpga...\n");}// stringelse if ((strcmp(argv[i],"-i")==0) || (strcmp(argv[i],"--iface")==0)){if (i+1<argc){char interface[32] = {0};strncpy(interface, argv[i+1], 32);if (debug)printf("Used interface: %s\n", interface);i++;continue;} else {printf("Error: Interface for -i missing.\n");return 1;}}// numberelse if ((strcmp(argv[i],"-ru")==0) || (strcmp(argv[i],"--rateunit"))==0){if (i+1<argc && isdigit(argv[i+1][0])) {int rateunit = 0;rateunit = atoi(argv[i+1]);if (rateunit < 0 || rateunit > 1){printf("Error: Invalid parameter \"%d\" for --rateunit.\n", rateunit);printf(" Valid parameters:\n");printf("    0 - bytes\n");printf("    1 - bits\n");return 1;}if (debug)printf("Rateunit changed: %d\n", rateunit);i++;continue;}else{}}// only oneelse if (strcmp(argv[i],"--enable")==0){int enable = 0;enable = 1;}else{printf("Unknown parameter \"%s\". Use --help for help.\n",argv[i]);return 1;}}
}
2. 利用getopt函数完成
/**
解析命令选项示例#include <unistd.h>
extern char *optarg;   //选项的参数指针
extern int optind,    //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。
extern int opterr,   //当opterr=0时,getopt不向stderr输出错误信息。
extern int optopt;   //当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt中,getopt返回'?’、
int getopt(int argc, char * const argv[], const char *optstring);使用:
$ ./a.out -Wall -o hello.c*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>int debug_level = 0;#define _AUTHOR "Late Lee"
#define _VERSION_STR "1.0"
#define _DATE ""// 默认打印error等级
enum
{MSG_ERROR = 0,MSG_WARNING,MSG_INFO,MSG_DEBUG,MSG_MSGDUMP,MSG_EXCESSIVE,
};void ll_printf(int level, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));void ll_printf(int level, const char *fmt, ...)
{va_list ap;va_start(ap, fmt);if (debug_level >= level){
#ifdef CONFIG_DEBUG_SYSLOGif (wpa_debug_syslog) {vsyslog(syslog_priority(level), fmt, ap);} else {
#endif /* CONFIG_DEBUG_SYSLOG *///debug_print_timestamp();
#ifdef CONFIG_DEBUG_FILEif (out_file) {vfprintf(out_file, fmt, ap);fprintf(out_file, "\n");} else {
#endif /* CONFIG_DEBUG_FILE */vprintf(fmt, ap);printf("\n");
#ifdef CONFIG_DEBUG_FILE}
#endif /* CONFIG_DEBUG_FILE */
#ifdef CONFIG_DEBUG_SYSLOG}
#endif /* CONFIG_DEBUG_SYSLOG */}va_end(ap);
}void show_version(char* name)
{printf("%s by %s, version: %s\n", name, _AUTHOR, _VERSION_STR);
}void usage(char* name)
{show_version(name);printf("    -h,    short help\n");printf("    -v,    show version\n");printf("    -d,    debug level\n");exit(0);
}const char* my_opt = "hOo:W:d:";int main(int argc, char *argv[])
{int c;const char* p1 = NULL;const char* p2 = NULL;const char* p3 = NULL;while(1){c = getopt(argc, argv, my_opt);printf("optind: %d\n", optind);if (c < 0){break;}printf("option char: %x %c\n", c, c);switch(c){case 'd':debug_level = atoi(optarg);printf("debug level: %d\n", debug_level);break;case 'O':printf("optimization flag is open.\n\n");break;case 'o':printf("the obj is: %s\n\n", optarg);p1 = optarg;break;case 'W':printf("optarg: %s\n\n", optarg);p2 = optarg;break;case ':':fprintf(stderr, "miss option char in optstring.\n");break;case '?':case 'h':default:usage(argv[0]);break;//return 0;}}if (optind == 1){usage(argv[0]);}ll_printf(MSG_ERROR, "p1: %s p2: %s\n", p1, p2);return 0;
}

使用 getopt() 进行命令行处理

网络模块
日志模块
读取配置文件模块
内存池模块
缓存库模块
文件系统模块
管理后台模块
数据库模块

技巧类

Linux程序中预定义的几个调试宏

Linux下C语言编程中有几个很实用的调试宏

__LINE__ __FILE__  __FUNCTION__ __TIME__ __DATA__

这几个预定义宏是属于ANSI标准的,内置于编译器,全局性的变量,可以方便地实现代码跟踪调试,不是在哪个头文件中包含的,见下例:

#include <stdio.h>int main()
{printf("The file is %s.\n",__FILE__);printf( "The date is %s.\n", __DATE__ );printf( "The time is %s.\n", __TIME__ );printf( "This is line %d.\n", __LINE__ );printf( "This function is %s.\n", __FUNCTION__ );   return 0;
}

运行结果:

The file is macro.c.
The date is Aug 24 2012.
The time is 23:13:26.
This is line 8.
This function is main.

line 行数 文件名指令可以改变它的值,简单的讲,编译时,它们包含程序的当前行数和文件名。

DATE 宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。
TIME 宏指令包含程序编译的时间。时间用字符串表示,其形式为时:分:秒

__func__代表这条语句所在的函数的函数名

联合体用途

字节序有两种表示方法:大端法(big ending),小端法(little ending)。网络字节序采用的是大端法。主机字节序不同的CPU采用的方法不一样,可以通过代码来查看自己主机的字节序。

  • 大端法:高位字节排放在内存低地址端,低位字节排放在内存的高地址端。
  • 小端法:低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
    看一个unsigned short 数据,它占2个字节,给它赋值0x1234。
  • 若采用的大端法,则其低地址端应该存放的是0x12;
  • 若采用的小端法,则其低地址端应该存放的是0x34;
    可以通过联合体来获得其高低地址的数据。测试主机字节序的代码:
typedef union{unsigned short value;unsigned char bytes[2];
}Test;int main(void)
{Test test_value;test_value.value = 0x1234;if(test_value.bytes[0] == 0x12 && test_value.bytes[1] == 0x34){printf("big ending");}else if(test_value.bytes[0] == 0x34 && test_value.bytes[1] == 0x12){printf("little ending");}else{printf("use test_value error");}return 0;
}

工具类

自定义日志的调试打印信息
#define TRACE_NONE      0
#define TRACE_FATAL     1
#define TRACE_ERROR     2
#define TRACE_WARNING   3
#define TRACE_INFO      4
#define TRACE_DEBUG     5#define TRACE_LEN_MAX    64extern int  *TraceLevel;
extern char TraceName[TRACE_LEN_MAX + 1];#define Log(A, format,args...) \((TraceLevel == NULL || TraceName == NULL || *TraceLevel < (A)) ? 0 : LogMsg(A, __FILE__, __LINE__, format, ##args))#define LogFatal(format,args...) \Log(TRACE_FATAL, format, ##args)
#define LogError(format,args...) \Log(TRACE_ERROR, format, ##args)
#define LogWarning(format,args...) \Log(TRACE_WARNING, format, ##args)
#define LogInfo(format,args...) \Log(TRACE_INFO, format, ##args)
#define LogDebug(format,args...) \Log(TRACE_DEBUG, format, ##args)
int LogMsg(int level, const char *filename,int line, const char *fmt, ...)
{va_list      ap;FILE         *fp;char         sLogFile[128 + 1];char         sCurrTime[6 + 1];struct timeb tTimeB;char         sMilliTM[4];memset(sLogFile, 0, sizeof(sLogFile));LogFile(sLogFile);GetTime_HHMMSS(sCurrTime);memset(&tTimeB, 0, sizeof(tTimeB));    ftime(&tTimeB);snprintf(sMilliTM, sizeof(sMilliTM), "%03d", tTimeB.millitm);fp = fopen(sLogFile, "a+");if (fp != (FILE*)NULL) {fprintf(fp, "[%08d][%.6s:%.3s][%16s][%04d][%7s]",getpid(), sCurrTime, sMilliTM, filename, line, g_LevelDsp[level]);va_start(ap, fmt);vfprintf(fp, fmt, ap);va_end(ap);fprintf(fp, "\n");fflush(fp);fclose(fp);}return 0;
}

再在后台进程中设置TraceLevel和TraceName即可。

获取当前系统日期、时间
/*******************************************************************************  函数名称: GetDate**  功能描述: 取当前系统日期                           **  当前版本: 1.0.0.0                                                    **  作    者:                                             **  修    改:                                                        **  输入参数:**  输出参数: char * psDate  -- 系统日期, 格式为yyyymmdd**  返回结果:int0    --->  成功****************************************************************************/
int GetDate(char * psDate)
{time_t nSeconds;struct tm * pTM;time(&nSeconds);pTM = localtime(&nSeconds);/* 系统日期, 格式:YYYYMMDD */sprintf( psDate,"%04d%02d%02d",pTM->tm_year + 1900, pTM->tm_mon + 1,pTM->tm_mday );return 0;
}
/*******************************************************************************  函数名称: GetTime**  功能描述: 取当前系统时间                           **  当前版本: 1.0.0.0                                                    **  作    者:                                            **  修    改:                                                        **  输入参数:**  输出参数: char * psTime  -- 系统时间, 格式为HHMMSS**  返回结果:int0    --->  成功****************************************************************************/
int GetTime(char * psTime)
{time_t nSeconds;struct tm * pTM;time(&nSeconds);pTM = localtime(&nSeconds);/* 系统时间, 格式:HHMMSS */sprintf( psTime,"%02d%02d%02d",pTM->tm_hour,pTM->tm_min, pTM->tm_sec);return 0;
}
/*******************************************************************************  函数名称: GetDateTime**  功能描述: 取当前系统日期和时间                           **  当前版本: 1.0.0.0                                                    **  作    者:                                            **  修    改:                                                        **  输入参数:**  输出参数: char * psDateTime  -- 系统日期时间, 格式为yyyymmddHHMMSS**  返回结果:int0    --->  成功****************************************************************************/
int GetDateTime(char * psDateTime)
{time_t nSeconds;struct tm * pTM;time(&nSeconds);pTM = localtime(&nSeconds);/* 系统日期和时间, 格式:yyyymmddHHMMSS */sprintf( psDateTime,"%04d%02d%02d%02d%02d%02d",pTM->tm_year + 1900, pTM->tm_mon + 1,pTM->tm_mday,pTM->tm_hour,pTM->tm_min, pTM->tm_sec );return 0;
}

调用的时候定义一个char数组,大小为日期的长度大小加1,然后直接调用上面的函数,参数为数组名即可。
  当然,还有其他许多关于日期、时间操作的函数,比如不同日期、时间格式间的转换等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/55119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据毕业设计选题推荐-重庆旅游景点数据分析系统-Python-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

基于微信开发助手企鹅音乐微信小程序的设计与实现(源码+文档+讲解)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

数据结构:线性表的链式表示

目录 基本组成 链表的类型 主要操作 初始化&#xff1a; 带头结点 不带头结点 插入操作 删除操作&#xff1a; 查找操作&#xff1a; 求表长&#xff1a; 建立单链表&#xff1a; 头插法&#xff1a; 尾插法&#xff1a; 双链表&#xff1a; 查找操作 插入操作…

【自动驾驶】对2D框的四条边同时缩进

对【自动驾驶】随机缩进2D框的一条边-CSDN博客进行补充。 所以这里直接进入正题&#xff0c;怎么做才能对每条边进行缩进&#xff1f; 待补充。

QT学习笔记之绘图

或许有人会等你到天黑&#xff0c;但是你不该在天黑后再找他&#xff08;她&#xff09;。 1.绘图事件 在ui文件中添加一个按钮&#xff0c;同时在资源文件中添加一个名字为1.jpg的图片。 widget.cpp #include "widget.h" #include "ui_widget.h" #incl…

这条挣钱的路,离我好遥远啊

近日&#xff0c;笔者在发表的《乱篇弹&#xff08;54&#xff09;让子弹飞》一文中写道&#xff1a;“ 当然&#xff0c;笔者在《博客中国-狼头长啸的作家专栏》耕耘期间&#xff0c;也赚了一些用以补贴自己养老的‘ 散碎银两’。那么笔者是否可以依照知乎网的‘申请开通权限’…

支付宝远程收款跳转码接口api之工作证跳转收款码

1、在制作工作证跳转收款之前需要在支付宝上开通工作证 2、然后获取支付宝账户信息、收款码等信息 3、将所需信息填入如下代码之中 const axios require(axios); const authCode 从客户端接收到的授权码;axios({method: post,url: https://openapi.alipay.com/alipay.syst…

SpringCloud入门(八)Feign自定义配置

一、Feign自定义配置 Feign可以支持很多的自定义配置&#xff0c;如下表所示&#xff1a; - 类型&#xff1a; feign.Logger.Level 作用 &#xff1a;修改日志级别 说明 &#xff1a; 包含四种不同的级别&#xff1a;NONE、BASIC、HEADERS、FULL - 类型&a…

用通义灵码如何快速合理解决遗留代码问题?

本文首先介绍了遗留代码的概念&#xff0c;并对遗留代码进行了分类。针对不同类型的遗留代码&#xff0c;提供了相应的处理策略。此外&#xff0c;本文重点介绍了通义灵码在维护遗留代码过程中能提供哪些支持。 什么是遗留代码 与过时技术相关的代码&#xff1a; 与不再受支持的…

Python如何配置环境变量详解

一、概述 前提&#xff1a;已安装 Python&#xff0c;如下图&#xff1a; 1.1 检查是否已配置成功&#xff08;选&#xff09; 1 2 3 4 5 1. 打开运行窗口 (1) 快捷键 : Win r&#xff0c;并输入 cmd (2) 直接输入: Python 2. 若有下列提示&#xff0c;即为 安装成功…

星辰计划04-深入理解kafka的消息存储和索引设计

消息存储 提到存储不得不说消息的读写&#xff0c;那么kafka他是如何读写数据的呢&#xff1f; 读取消息 1.通过debug(如何debug) 我们可以得到下面的调用栈&#xff0c;最终通过FileRecords来读取保存的数据 写入消息 1.通过debug(如何debug) 我们可以得到下面的调用栈&am…

【HTTP 和 HTTPS详解】3

HTTP 状态代码 HTTP 状态代码是服务器发送给客户端的三位数字&#xff0c;用于指示客户端请求的结果。它们分为五类&#xff1a;信息性&#xff08;100-199&#xff09;、成功&#xff08;200-299&#xff09;、重定向&#xff08;300-399&#xff09;、客户端错误&#xff08…

怎么不用付费直接编辑pdf?5款pdf在线编辑器免费推荐给你!

在我们日常工作中&#xff0c;可能会经常需要直接编辑修改pdf内容&#xff0c;例如&#xff0c;在将文档发送给其它人之前&#xff0c;您可能需要进行一些修改&#xff1b;或者当扫描的文本出现错误时&#xff0c;您也需要进行修正。此时&#xff0c;如果有一款在线编辑器&…

【C++笔记】初始模版和STL简介

【C笔记】初始模版和STL简介 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】初始模版和STL简介前言一.初始模版1.1泛型编程1.2函数模版1.3类模板 二.STL简介2.1什么是STL2.2STL的版本2.3STL的六大组件2.4STL的重要…

Vue项目之Element-UI(Breadcrumb)动态面包屑效果 el-breadcrumb

效果预览 需要导航的页面Vue.js 最笨的方法就是在每个需要面包屑的页面中固定写好 <template><div class="example-container"><el-breadcrumb separator="/"

Tableau数据可视化入门

目录 一、实验名称 二、实验目的 三、实验原理 四、实验环境 五、实验步骤 1、Tableau界面引导 2、数据来源 3、数据预处理操作 4、制作中国各个地区的利润图表 4.1条形图 4.2气泡图 5、制作填充地球图 一、实验名称&#xff1a; 实验一&#xff1a;Tableau数据可视…

vue使用indexedDB缓存教程

1.前端缓存几种方式: cookie、localStorage、sessionStorage、indexedDB&#xff0c;下面详细介绍indexedDB 2.完整代码 class DBManager {dbName: any null;version: any null;db: any null;/*** 初始化数据库名、版本* param dbName* param version*/constructor(dbName…

在C#中使用JSON

JSON简介 1. 什么是 JSON&#xff1f; JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式。它的语法基于 JavaScript 对象表示法&#xff0c;简单、易读&#xff0c;同时被许多编程语言支持。尽管它来源于 JavaScript&#xff0c;但它并不依…

RTE大会报名丨 重塑语音交互:音频技术和 Voice AI,RTE2024 技术专场第一弹!

Voice AI 实现 human-like 的最后一步是什么&#xff1f; AI 视频爆炸增长&#xff0c;新一代编解码技术将面临何种挑战&#xff1f; 当大模型进化到实时多模态&#xff0c;又将诞生什么样的新场景和玩法&#xff1f; 所有 AI Infra 都在探寻规格和性能的最佳平衡&#xff0…

美畅物联丨GB/T 28181系列之TCP/UDP被动模式和TCP主动模式

GB/T 28181《安全防范视频监控联网系统信息传输、交换、控制技术要求》作为我国安防领域的重要标准&#xff0c;为视频监控系统的建设提供了全面的技术指导和规范。该标准详细规定了视频监控系统的信息传输、交换和控制技术要求&#xff0c;在视频流传输方面&#xff0c;GB/T 2…