首页 文章

C宏将字符串转换为pascal字符串类型

提问于
浏览
0

我想一些宏的想法,将预处理器定义的字符串转换为pascal类型字符串,然后能够使用宏来初始化const char数组等 .

像这样的东西会很棒:

#define P_STRING_CONV(str) ...???...

const char *string = P_STRING_CONV("some string");

struct
{
    char str[30];
    ...
}some_struct = {.str = P_STRING_CONV("some_other_string")};

我已经尝试过这样的事:

#define DEFINE_PASCAL_STRING(var, str, strlen) struct {uint8_t len; char content[strlen-1];} (var) = {sizeof(str)-1, (str)}

(可以删除strlen参数,但我需要一个已定义的大小 . )

这工作正常,但不能用于初始化结构中的元素 . 对于const char数组,我需要将它转换为其他变量 .

有什么好主意吗?

2 回答

  • 1

    您可以将宏拆分为两个:

    #define PASCAL_STRING_TYPE(size) struct { unsigned char len; char content[(size) - 1]; }
    #define PASCAL_STRING_INIT(str) { .len = sizeof(str) - 1, .content = (str) }
    

    然后像这样使用它:

    static const PASCAL_STRING_TYPE(100) foo = PASCAL_STRING_INIT("foo");
    
    struct bar {
       int answer;
       PASCAL_STRING_TYPE(100) question;
    };
    static const struct bar quux = {
        .answer = 42,
        .question = PASCAL_STRING_INIT("The Answer")
    };
    

    (未经测试 . )

  • 0

    将字符串转换为pascal字符串类型

    要转换字符串文字, _Generic 和复合文字将接近OP目标 .

    为了获得更好的解决方案,更多细节和示例用例将有助于说明OP的目标 .

    #define P_STRING_CONV(X) _Generic((X)+0, \
      char *: &((struct {char len; char s[sizeof(X)-1]; }){ (char)(sizeof(X)-1), (X) }).len \
      )
    
    void dump(const char *s) {
      unsigned length = (unsigned char) *s++;
      printf("L:%u \"", length);
      while (length--) {
        printf("%c", *s++);
      }
      printf("\"\n");
    }
    
    int main(void) {
      dump(P_STRING_CONV(""));
      dump(P_STRING_CONV("A"));
      dump(P_STRING_CONV("AB"));
      dump(P_STRING_CONV("ABC"));
      return 0;
    }
    

    产量

    L:0 ""
    L:1 "A"
    L:2 "AB"
    L:3 "ABC"
    

    @Jonathan Leffler建议创建的类似pascal的字符串也包含终止空字符 . 要使用上面的代码执行此操作,只需将 sizeof(X)-1 更改为 sizeof(X) 即可 . 然后通过访问 pascal_like_string + 1 ,代码具有指向有效C字符串的指针 .


    (X)+0 将数组类型转换为指针

    sizeof(X)-!!sizeof(X) 生成字符串文字的大小,不计算其\ 0 . 至少1 .

    struct {char len; char s[sizeof(X)-!!sizeof(X)]; } 是一个正确大小的帕斯卡式结构 .

    (struct {char len; char s[sizeof(X)-!!sizeof(X)]; }){ (char)(sizeof(X)-1), (X) } 是复合文字 .


    以下将C字符串转换为类似字符串的pascal . 请注意,作为像字符串一样的pascal,没有 '\0' .

    #include <limits.h>
    #include <stdlib.h>
    #include <string.h>
    char *pstring_convert(char *s) {
      size_t len = strlen(s);
      assert(len <= UCHAR_MAX);
      memmove(s+1, s, len);
      s[0] = (char) (unsigned char) len;
      return s;
    }
    

相关问题