This question is related to Concatenate string literal with char literal, but is slightly more complex.
I would like to create a string literal, where the first character of the string is the length of the string, and the second character is a constant. This is how it is being done currently:
const char myString[] =
{
0x08,
SOME_8_BIT_CONSTANT,
'H',
'e',
'l',
'l',
'o',
0x00
};
Ideally, I would like to replace it with something like:
const char myString[] = BUILD_STRING(0xAA, "Hello");
I tried implementing it like this:
#define STR2(S) #S
#define STR(S) STR2(S)
#define BUILD_STRING(C, S) {(sizeof(S)+2), C, S}
const char myString[] = BUILD_STRING(0xAA, "Hello");
but it expands to:
const char myString[] = {(sizeof("Hello")+2), 0xAA, "Hello"};
and the compiler doesn't seem to like mixing numbers and strings.
Is there any way to do this?
To get the first character of a string, we can call charAt() on the string, passing 0 as an argument. For example, str. charAt(0) returns the first character of str . The String charAt() returns the character of a string at the specified index.
Use a %s format (or, better, %255s format) for the two scanf() calls. Then pass firstname[0] and lastname to printf() . You might want to think about using tolower() from <ctype. h> on the first letter, and maybe on the last name too.
'C' also allows us to initialize a string variable without defining the size of the character array. It can be done in the following way, char first_name[ ] = "NATHAN"; The name of Strings in C acts as a pointer because it is basically an array.
You could in-place define a structure to hold the prefix and the rest, conveniently initialize it, and then treat the whole struct
as a char
array (not a strict-aliasing violation because standard C lets you treat any object as a char
array).
Technically, you're not guaranteed that the compiler won't insert padding between the prefix and the rest, but in practice you can count on it.
#define BUILD_STRING(C, S) \
((char const*)&(struct{ char const p[2]; char const s[sizeof(S)]; })\
{ {(sizeof(S)+2), C}, S})
const char *myString = BUILD_STRING(0xAA, "Hello");
#include <stdio.h>
int main()
{
printf("%d, %#hhX, '%s'\n", myString[0], myString[1], myString+2);
//PRINTS: 8, 0XAA, 'Hello'
}
Edit:
If you're paranoid about the possibility of padding, here's one way to statically assert none is inserted:
#define BUILD_STRING__(S) \
char const p[2]; char const s[sizeof(S)]
#define BUILD_STRING(C, S) \
((char const*)&(struct{BUILD_STRING__(S); \
_Static_assert(sizeof(S)+2== \
sizeof(struct{BUILD_STRING__(S);_Static_assert(1,"");}),""); \
}){ {sizeof(S)+2, C}, S})
Alternatively, using the first version with the (nonstandard)
__attribute((__packed__))
should do the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With