Unlock Fast C Utilities: Struct Sizes, CPU Temp, File Size, IP & More
This article presents a collection of handy C code snippets that demonstrate how to quickly obtain struct member sizes and offsets, read CPU temperature, determine file sizes, fetch system timestamps, retrieve MAC and IP addresses, perform file I/O, display progress bars, format log output, and enable core dump generation, each accompanied by sample usage and expected results.
Quickly Get Struct Member Size and Offset
Defines macros GET_MEMBER_SIZE and GET_MEMBER_OFFSET to compute the size and offset of a struct member, then demonstrates their use with two example structures and a test program that prints the sizes, offsets and the total size of the structure.
#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 argc, char *argv[]){
printf("GET_MEMBER_SIZE(test_struct1, a) = %ld
", GET_MEMBER_SIZE(test_struct1, a));
printf("GET_MEMBER_SIZE(test_struct1, c) = %ld
", GET_MEMBER_SIZE(test_struct1, c));
printf("GET_MEMBER_SIZE(test_struct1, b) = %ld
", GET_MEMBER_SIZE(test_struct1, b));
printf("GET_MEMBER_SIZE(test_struct1, d) = %ld
", GET_MEMBER_SIZE(test_struct1, d));
printf("GET_MEMBER_SIZE(test_struct1, e) = %ld
", GET_MEMBER_SIZE(test_struct1, e));
printf("test_struct1 size = %ld
", sizeof(test_struct1));
printf("GET_MEMBER_OFFSET(a): %ld
", GET_MEMBER_OFFSET(test_struct1, a));
printf("GET_MEMBER_OFFSET(c): %ld
", GET_MEMBER_OFFSET(test_struct1, c));
printf("GET_MEMBER_OFFSET(b): %ld
", GET_MEMBER_OFFSET(test_struct1, b));
printf("GET_MEMBER_OFFSET(d): %ld
", GET_MEMBER_OFFSET(test_struct1, d));
printf("GET_MEMBER_OFFSET(e): %ld
", GET_MEMBER_OFFSET(test_struct1, e));
return 0;
}Get CPU Temperature
Reads the temperature from the Linux thermal zone file, splits the value into integer and decimal parts, and prints it in degrees Celsius.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define CPU_TEMP_FILE0 '/sys/devices/virtual/thermal/thermal_zone0/temp'
typedef struct cpu_temperature {
int integer_part;
int decimal_part;
} cpu_temperature_t;
cpu_temperature_t get_cpu_temperature(const char *_cpu_temp_file){
FILE *fp = NULL;
cpu_temperature_t cpu_temperature = {0};
int temp = 0;
fp = fopen(_cpu_temp_file, "r");
if (NULL == fp){
printf("fopen file error
");
return cpu_temperature;
}
fscanf(fp, "%d", &temp);
cpu_temperature.integer_part = temp / 1000;
cpu_temperature.decimal_part = (temp % 1000) / 100;
fclose(fp);
return cpu_temperature;
}
int main(int argc, char *argv[]){
cpu_temperature_t cpu_temperature = {0};
cpu_temperature = get_cpu_temperature(CPU_TEMP_FILE0);
printf("cpu_temperature = %d.%d ℃
", cpu_temperature.integer_part, cpu_temperature.decimal_part);
return 0;
}Get File Size
Opens a file, seeks to the end, uses ftell to obtain its size, and prints the result.
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
long get_file_size(const char *_file_name){
FILE *fp = fopen(_file_name, "r");
if (NULL == fp){
printf("fopen error
");
return -1;
}
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
fclose(fp);
return size;
}
int main(){
#define FILE_NAME './get_file_size'
long file_size = get_file_size(FILE_NAME);
printf("file_size = %ld
", file_size);
return 0;
}Get System Timestamp (ms)
Uses gettimeofday to obtain the current time with microsecond precision and converts it to milliseconds.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
long long get_sys_time_ms(void){
long long time_ms = 0;
struct timeval sys_current_time;
gettimeofday(&sys_current_time, NULL);
time_ms = ((long long)sys_current_time.tv_sec * 1000000 + sys_current_time.tv_usec) / 1000;
return time_ms;
}
int main(int argc, char *argv[]){
long long cur_sys_time = get_sys_time_ms();
printf("cur_sys_time = %lld ms
", cur_sys_time);
return 0;
}Get MAC Address
Opens a socket, uses ioctl with SIOCGIFHWADDR to retrieve the hardware address of a network interface, formats it as a hex string, and prints it.
#include <stdio.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
int get_netif_mac(const char *_ifr_name, uint8_t *_mac){
int32_t ret = -1;
struct ifreq m_ifreq;
int32_t sock = 0;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0){
printf("socket err
");
goto err;
}
strcpy(m_ifreq.ifr_name, _ifr_name);
ret = ioctl(sock, SIOCGIFHWADDR, &m_ifreq);
if (ret < 0){
printf("ioctl err:%d
", ret);
goto err;
}
snprintf((char *)_mac, 32, "%02x%02x%02x%02x%02x%02x",
(uint8_t)m_ifreq.ifr_hwaddr.sa_data[0],
(uint8_t)m_ifreq.ifr_hwaddr.sa_data[1],
(uint8_t)m_ifreq.ifr_hwaddr.sa_data[2],
(uint8_t)m_ifreq.ifr_hwaddr.sa_data[3],
(uint8_t)m_ifreq.ifr_hwaddr.sa_data[4],
(uint8_t)m_ifreq.ifr_hwaddr.sa_data[5]);
return 0;
err:
return -1;
}
int main(int argc, char **argv){
char mac_str[32] = {0};
get_netif_mac("wlan1", mac_str);
printf("mac = %s
", mac_str);
return 0;
}Get IP Address
Creates a socket, uses ioctl with SIOCGIFADDR to obtain the IPv4 address of a given interface, and prints it.
#include <stdio.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
int get_local_ip(const char *_ifr_name, char *_ip){
int ret = -1;
int sockfd;
struct sockaddr_in sin;
struct ifreq ifr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == sockfd){
printf("socket error
");
return ret;
}
strncpy(ifr.ifr_name, _ifr_name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ - 1] = 0;
if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0){
printf("ioctl error
");
close(sockfd);
return ret;
}
memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
int ip_len = snprintf(_ip, 32, "%s", inet_ntoa(sin.sin_addr));
close(sockfd);
ret = ip_len;
return ret;
}
int main(int argc, char **argv){
char ip_str[32] = {0};
get_local_ip("wlan1", ip_str);
printf("ip = %s
", ip_str);
return 0;
}File Operations (Read/Write)
Provides two helper functions file_opt_write and file_opt_read that encapsulate binary file writing and reading, then demonstrates their use with a test structure.
#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!
", filename);
return -1;
}
num = fwrite(ptr, 1, size, fp);
if (num != size){
fclose(fp);
printf("write %s file error!
", 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!
", filename);
return -1;
}
num = fread(ptr, 1, size, fp);
if (num != size){
fclose(fp);
printf("write %s file error!
", filename);
return -1;
}
fclose(fp);
return num;
}
typedef struct _test_struct {
char a;
char c;
short b;
int d;
} test_struct;
int main(int argc, char *argv[]){
#define FILE_NAME './test_file'
test_struct write_data = {0};
write_data.a = 1;
write_data.b = 2;
write_data.c = 3;
write_data.d = 4;
printf("write_data.a = %d
", write_data.a);
printf("write_data.b = %d
", write_data.b);
printf("write_data.c = %d
", write_data.c);
printf("write_data.d = %d
", write_data.d);
file_opt_write(FILE_NAME, (test_struct*)&write_data, sizeof(test_struct));
test_struct read_data = {0};
file_opt_read(FILE_NAME, (test_struct*)&read_data, sizeof(test_struct));
printf("read_data.a = %d
", read_data.a);
printf("read_data.b = %d
", read_data.b);
printf("read_data.c = %d
", read_data.c);
printf("read_data.d = %d
", read_data.d);
return 0;
}Progress Bar
Implements a simple textual progress bar that updates in place based on the current size and total size of an operation.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
typedef struct _progress {
int cur_size;
int sum_size;
} progress_t;
void progress_bar(progress_t *progress_data){
int percentage = 0;
int cnt = 0;
char proc[102];
memset(proc, '\0', sizeof(proc));
percentage = (int)(progress_data->cur_size * 100 / progress_data->sum_size);
printf("percentage = %d %%
", percentage);
if (percentage <= 100){
while (cnt <= percentage){
printf("[%-100s] [%d%%]\r", proc, cnt);
fflush(stdout);
proc[cnt] = '#';
usleep(100000);
cnt++;
}
}
printf("
");
}
int main(int argc, char *argv[]){
progress_t progress_test = {0};
progress_test.cur_size = 65;
progress_test.sum_size = 100;
progress_bar(&progress_test);
return 0;
}Log Output Formatting
Defines a macro LOG_D that prefixes log messages with file name, line number and function name, then demonstrates its use with various data types.
#include <stdio.h>
#define LOG_D(fmt, args...) do { \
printf("<<File:%s Line:%d Function:%s>> ", __FILE__, __LINE__, __FUNCTION__); \
printf(fmt, ##args); \
} while(0)
int main(int argc, char *argv[]){
char ch = 'a';
char str[10] = "ZhengN";
float float_val = 10.10f;
int num = 88;
double double_val = 10.123456;
LOG_D("Character: %c
", ch);
LOG_D("String: %s
", str);
LOG_D("Float: %f
", float_val);
LOG_D("Integer: %d
", num);
LOG_D("Double: %lf
", double_val);
LOG_D("Octal: %o
", num);
LOG_D("Hex: %x
", num);
return 0;
}Generate Core Dump on Segmentation Fault
Sets the core dump size limit to unlimited, configures the core pattern, and deliberately triggers a segmentation fault to produce a core file.
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
#define SHELL_CMD_CONF_CORE_FILE 'echo /var/core-%e-%p-%t > /proc/sys/kernel/core_pattern'
#define SHELL_CMD_DEL_CORE_FILE 'rm -f /var/core*'
static int enable_core_dump(void){
int ret = -1;
int resource = RLIMIT_CORE;
struct rlimit rlim;
rlim.rlim_cur = 1 ? RLIM_INFINITY : 0;
rlim.rlim_max = 1 ? RLIM_INFINITY : 0;
system(SHELL_CMD_DEL_CORE_FILE);
if (0 != setrlimit(resource, &rlim)){
printf("setrlimit error!
");
return -1;
} else {
system(SHELL_CMD_CONF_CORE_FILE);
printf("SHELL_CMD_CONF_CORE_FILE
");
return 0;
}
return ret;
}
int main(int argc, char **argv){
enable_core_dump();
printf("==================segmentation fault test==================
");
int *p = NULL;
*p = 1234; // intentional crash
return 0;
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Linux
Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
