结构体中长度为0的字符数组
在C语言的结构体中,有一种特殊用法,在结构体的末尾放置一个长度为0的字符数组,结构体倒数第二个位置放置一个整型变量len
。其典型样例如下:
typedef struct dynamic_value {
int flag;
int len;
char val[0];
}s_flv;
本文针对其特征,用法及适用场合予以简单介绍。
特征
- 最后的字符数组
val
长度为0,不占用额外的内存空间 - 倒数第二个元素为一整型变量,用于存储字符数组的真实长度
val
实际指向的是结构体s_flv
之后的内存空间- 字符数组的大小可以在定义结构体变量时动态指定
s_flv.len
- 结构体元素个数不限,样例为典型模式,其中的
flag
作为标签用以标识不同的数据
用法
- 按
s_flv
格式写入数据到文件
#include <stdio.h>
static void write_flv(FILE *fp, int flag, char *val)
{
int len = 0;
if(val == NULL)
val = "";
else
len = strlen(val);
fwrite(&flag, sizeof(flag), 1, fp); // 写入标识
fwrite(&len, sizeof(len), 1, fp); // 写入字符数组长度
fwrite(val, len, 1, fp); // 写入长度为len的字符串
}
- 读取文件
#include <stdio.h>
static int read_flv(char *file, char *val)
{
char buf[32]; // 假定字符数组长度小等于32
char *p = buf;
FILE *fp = fopen(file, "r");
if(!fp)
return -1;
if(fread(buf, 2*sizeof(int), 1, fp) <= 0) // 读取前两个整型数据,获取字符数组长度
return -1;
s_flv *flv = (s_flv *)p; // 定义s_flv结构体,存储数据
fread(val, flv->len, 1, fp); // 读取字符数组
flose(fp);
return 0;
}
- 说明
- 每执行一次
fread
或fwrite
函数,文件指针就往后偏移相应的读取长度或写入长度 read_flv
定义flv
时,从buf
中可以获取到数组长度,然后使用fread
读取相应长度的数据即可取出字符数组的内容。- 使用以上方法生成的文件内容是二进制文件,许多字符是不可打印字符,所以使用
cat
指令无法正常显示文件内容
- 每执行一次
上面描述的方法是将s_flv
类型的数据存入文件,但如果不想存入文件,那么该如何为其分配内存呢,下面来看一下:
#include <stdio.h>
#include <stdlib.h>
// 定义s_flv指针变量
int size = 10;
s_flv *flv = (s_flv *)malloc(sizeof(s_flv) + size);
flv->len = size;
flv->val = flv + sizeof(s_flv);
// 释放指针
free(flv);
适用场合
json
文件的读写- 不定长度字符串的读写
扩展阅读
版权声明:本博客所有文章除特殊声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明出处 litreily的博客!