概述
做项目,掌握以下方法,可提高开发效率,把时间全部放在需求上。
1、快速获取结构体成员大小
#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;
}
运行结果:
2、文件操作
文件操作平时用得很多,为了方便使用,可以自己根据实际需要再封装一层:
#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_data_info
{
char a;
char c;
short b;
int d;
}test_data_info;
int main(int arc, char* argv[])
{
#define FILE_NAME "./test_file"
test_data_info 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_data_info*)&write_data, sizeof(test_data_info));
test_data_info read_data = { 0 };
file_opt_read(FILE_NAME, (test_data_info*)&read_data, sizeof(test_data_info));
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;
}
运行结果:
3、进度条
有时候,加上进度条可以比较方便知道当前的下载进度、写入文件的进度等。
#include <stdio.h>
#include <string.h>
#include <windows.h>
typedef struct _progress_t
{
int cur_size;
int sum_size;
}progress_t;
void progress_bar(progress_t* progress_data)
{
int percentage = 0;
int cnt = 0;
char proBuf[102];
memset(proBuf, '\0', sizeof(proBuf));
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", proBuf, cnt);
fflush(stdout);
proBuf[cnt] = '#';
Sleep(1);
cnt++;
}
}
printf("\n");
}
int main(int arc, char* argv[])
{
progress_t progress_test = { 0 };
progress_test.cur_size = 82;
progress_test.sum_size = 100;
progress_bar(&progress_test);
return 0;
}
运行结果:
4、日志输出
日志输出常常需要带一些格式。最简单的方式如:
// 定义日志等级
typedef enum {
LOG_DEBUG,
LOG_INFO,
LOG_WARNING,
LOG_ERROR,
} log_level_t;
// 封装的日志函数
void log_message(log_level_t level, const char* message, const char* file, int line) {
switch (level) {
case LOG_DEBUG:
printf("DEBUG: %s (%s:%d)\n", message, file, line);
break;
case LOG_INFO:
printf("INFO: %s (%s:%d)\n", message, file, line);
break;
case LOG_WARNING:
printf("WARNING: %s (%s:%d)\n", message, file, line);
break;
case LOG_ERROR:
printf("ERROR: %s (%s:%d)\n", message, file, line);
break;
default:
break;
}
}
// 在代码中使用封装的日志函数
int main() {
log_message(LOG_INFO, "This is an info message", __FILE__, __LINE__);
log_message(LOG_DEBUG, "This is a debug message", __FILE__, __LINE__);
log_message(LOG_WARNING, "This is a warning message", __FILE__, __LINE__);
log_message(LOG_ERROR, "This is an error message", __FILE__, __LINE__);
return 0;
}
运行结果:
5、总结
介绍完毕,希望能帮助到你,蟹蟹参阅!!!