C语言结构体中char data[0]的用法

1. char data[0]的存在形式

char data[0]的存在形式一般如下图中的伪代码所示,多数情况都是放在结构体的最后,其不占用结构的空间(sizeof(struct AAA)的结果不包含char xxx_data[0]),xxx_data[0]的存在只是一个指针的占位符,当结构体分配的指针分配的内存多于结构体本身应占有的内存时,多于的内存将会由这个 "xxx_data"的指针所指向,并且可以通过结构体去使用这块内存。

这就类似相当于结构体“包含”了一段可变长的空间,从而克服了C语言结构体类型需要有明确长度的“缺陷”。(注意:我这里的包含加了“”,因为实际并不是包含关系)。

typedef struct{
    ...
    int  xxx_len;
    char xxx_data[0];
}pAAA;

2. 实例说明

(1)示例说明:

下面的示例展示了,定义了一个结构体,包含了一个int型的len和一个char data[0],然后将结构体的指针和要读取文件的路径传入read_file_data这个函数。

该函数中会根据文件的实际长度,为结构体和data[0] malloc内存。读取文件内容并给结构体成员"len" 和 "data[0]" 所指的空间赋值。

最后在main函数里输出文件的长度,和文件内容。

(2)代码

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #define FILE_NAME  "./test.txt"

 typedef struct{
       int len;
       char data[0];
 }str_test;
 
 
 void read_file_data(char * fileName, str_test **str)
 {
     FILE *pFile = NULL;
     size_t fileLen = 0;
     size_t len = 0;
     char *pHead = NULL;
     pFile =  fopen(fileName, "r");
     if (!pFile){
         return;
     }
     //获取文件的长度
     fseek(pFile, 0, SEEK_END);
     fileLen = ftell(pFile);
     fseek(pFile, 0, SEEK_SET);
     //malloc时申请内存的长度=str_test结构体的程度+文件的长度+1,结构长度外的内存用于存储文件数据
     *str = (str_test *)malloc(sizeof(str_test)+fileLen +1);
     if (!(*str)){
         return;
     }
     memset(*str, 0, sizeof(str_test)+fileLen+1);
     (*str)->len = fileLen;
     pHead = (*str)->data;
     do{
         len = fread(pHead, 1, 10, pFile);
         pHead += len;
     }while(len>0);
     fclose(pFile);
 }
 
 int main(void)
 {
     str_test *str = NULL;
     read_file_data(FILE_NAME, &str);
     if (str){
         printf("file_len=%d\n", str->len);
         printf("file_data=%s\n", str->data);
         free(str);
     }
     return 0;
 }

(3)test.txt文件内容:

111222333 hello world 666hoihg

(4)结果:

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值