Declaring Pascal-style strings in C

后端 未结 10 1236
渐次进展
渐次进展 2020-12-25 13:18

In C, is there a good way to define length first, Pascal-style strings as constants, so they can be placed in ROM? (I\'m working with a small embedded system with a non-GCC

相关标签:
10条回答
  • 2020-12-25 13:43

    This is why Variable Length Arrays were introduced in c99 (and to avoid the use of the "struct hack") IIRC, Pascal-strings were limited to a maximal length of 255.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <limits.h> // For CHAR_BIT
    
    struct pstring {
            unsigned char len;
            char dat[];
            };
    
    struct pstring *pstring_new(char *src, size_t len)
    {
    struct pstring *this;
    if (!len) len = strlen(src);
    
        /* if the size does not fit in the ->len field: just truncate ... */
    if (len >=(1u << (CHAR_BIT * sizeof this->len))) len = (1u << (CHAR_BIT * sizeof this->len))-1;
    
    this = malloc(sizeof *this + len);
    if (!this) return NULL;
    
    this->len = len;
    memcpy (this->dat, src, len);
    return this;
    }
    
    int main(void)
    {
    struct pstring *pp;
    
    pp = pstring_new("Hello, world!", 0);
    
    printf("%p:[%u], %*.*s\n", (void*) pp
            , (unsigned int) pp->len
            , (unsigned int) pp->len
            , (unsigned int) pp->len
            , pp->dat
            );
    return 0;
    }
    
    0 讨论(0)
  • 2020-12-25 13:47

    You can still use a const char * literal and an escape sequence as its first character that indicates the length:

    const char *pascal_string = "\x03foo";
    

    It will still be null-terminated, but that probably doesn't matter.

    0 讨论(0)
  • 2020-12-25 13:50

    GCC and clang (and possibly others) accept the -fpascal-strings option which allows you to declare pascal-style string literals by having the first thing that appears in the string be a \p, e.g. "\pfoo". Not exactly portable, but certainly nicer than funky macros or the runtime construction of them.

    See here for more info.

    0 讨论(0)
  • 2020-12-25 13:51

    You can define an array in the way you like, but note that this syntax is not adequate:

    const char *s = {3, 'f', 'o', 'o'};
    

    You need an array instead of a pointer:

    const char s[] = {3, 'f', 'o', 'o'};
    

    Note that a char will only store numbers up to 255 (considering it's not signed) and this will be your maximum string length.

    Don't expect this to work where other strings would, however. A C string is expected to terminate with a null character not only by the compiler, but by everything else.

    0 讨论(0)
提交回复
热议问题