將字符串轉換爲帕斯卡字符串類型
要轉換字符串文字,_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字符串的指針。
數組類型轉換爲指針
sizeof(X)-!!sizeof(X)
產生大小字符串的文字,不計算其\ 0。至少1.
struct {char len; char s[sizeof(X)-!!sizeof(X)]; }
是一個正確大小的pascal狀結構。
(struct {char len; char s[sizeof(X)-!!sizeof(X)]; }){ (char)(sizeof(X)-1), (X) }
是複合文字。
下面將一個C 串轉換爲像串帕斯卡。請注意,作爲類似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;
}
1.你爲什麼要這樣做?我認爲我並不真正瞭解你實際想要達到什麼目標。 –
主要的問題是,你似乎認爲類似Pascal的字符串與C字符串(指向char的指針或char的數組)是兼容的,它實際上並不自然。使用類似Pascal的字符串會解決什麼問題?你爲什麼要使用它們? –
至少,這些字符串應該保留一個NUL終止符,因此將它們的最大長度減少到254個字符。至少可以通過傳遞[address + 1]將它們用作const參數。 –