C 常见问题
东东 Lv4

判断大小端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdint.h>

int main(int argc, char const *argv[])
{
uint32_t val = 0x55; // 0x55 = 00 00 00 55, 55 是低位
uint8_t *p = (uint8_t *)&val;

printf("%02X %02X %02X %02X\n", p[0], p[1], p[2], p[3]);
// x86 平台: 输出 55 00 00 00 说明低位在低地址, 小端模式
// ARM 平台: 输出 55 00 00 00 说明低位在低地址, 小端模式

/* 快速判断小端模式 */
if(({volatile int val = 0x55; *(uint8_t*)&val == 0x55;}))
printf("OK\n");

return 0;
}

进度条实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
char buf[33] = {0};
memset(buf, ' ', sizeof(buf) - 1);

for (int i = 0; i < 32; i++)
{
buf[i] = '#';
float per = i == 31 ? 100.0 : (float)i / 32.0 * 100.0;
printf("\r [%s] %.0f%% %s ", buf, per, "346 KB/s");
sleep(1);
}

return 0;
}

也可以通过 .*s 实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main(int argc, char const *argv[])
{
char buf[33] = {0};
memset(buf, '#', sizeof(buf) - 1);

for (int i = 0; i < 32; i++)
{
float per = i == 31 ? 100.0 : (float)i / 32.0 * 100.0;
int left = (per / 100.0) * 32;
int right = 32 - left;
printf("\r[%.*s%*s] %.0f%% %s ", left, buf, right, "", per, "346 KB/s");
usleep(100000);
}

return 0;
}

导出成宏的形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#include <unistd.h>

#define START_PROGRESS_BAR(pbar, len) \
char __##pbar[len] = {0}; \
memset(__##pbar, '#', sizeof(__##pbar) - 1)

#define PROGRESS_BAR_RUNING(pbar, per, fmt, ...) ({ \
float p = per >= 100.0 ? 100.0 : per; \
int left = (p / 100.0) * (sizeof(__##pbar) - 1); \
int right = (sizeof(__##pbar) - 1) - left; \
printf("\r[%.*s%*s] %.0f%%" fmt, left, __##pbar, right, "", (float)per, __VA_ARGS__); \
})

int main(int argc, char const *argv[])
{
START_PROGRESS_BAR(mybar, 64);

for (int i = 0; i < 32; i++)
{
PROGRESS_BAR_RUNING(mybar, (float)i / 31 * 100.0, " %d KB/s", 105);
usleep(100000);
}

return 0;
}

简单项目的多语言功能

language.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "language.h"

lang_type_t lang_type = LANG_CN;

void lang_type_set(lang_type_t type)
{
if (type < 0 || type > _LANG_MAX)
return;

lang_type = type;
}

lang_type_t lang_type_get(void)
{
return lang_type;
}

const language_t lang = {
.About = {
"About",
"关于"
},
.Exit = {
"Exit",
"退出"
},
};

language.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#pragma once

#define LANG(lang_item) \
((lang_item).text[lang_type] ? \
(lang_item).text[lang_type] : "null")

typedef enum {
LANG_EN,
LANG_CN,
_LANG_MAX,
}lang_type_t;

typedef struct {
const char *text[_LANG_MAX];
} lang_item_t;

extern const language_t lang;
extern lang_type_t lang_type;

void lang_type_set(lang_type_t type);
lang_type_t lang_type_get(void);

/**
* 正则替换更改 item 名称:
* (LANG\(lang\.)oldname\) --> $1oldname)
*/
typedef struct {
/* 设置信息 */
lang_item_t About;
lang_item_t Exit;
}language_t;

使用举例:

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include "language.h"

int main(int argc, char const *argv[])
{
/* 设置语言类型 */
lang_type_set(LANG_CN);

/* 打印语言项 */
printf("%s\n", LANG(lang.About));

/* 打印所有语言项 */
for (int i = 0; i < sizeof(lang) / sizeof(lang_item_t); i++)
{
lang_item_t *l = (lang_item_t *)(&lang) + i;
printf("%s\n", LANG(*l));
}

return 0;
}

源文件来自于

 评论