问题
Sorry if this is solvable via Google -- I couldn't find anything.
char foo[4] = "abcd";
is invalid in C++ (due to the need for '\0' terminator) but IIRC valid in C -- is that correct?
I have a set of structs with a large number of "fixed length" character fields that are to be blank-padded and not '\0' terminated. I would like to be able to do the usual sort of struct initialization -- you know
mystruct bar = {17, "abcd", 0x18, "widget ", ...
But I can't do that in C++. One solution I guess would be to put all of the initialized structs like this into their own C (not ++) source module. The ugly, laborious solution that I am trying to avoid is
mystruct bar = {17, {'a', 'b', 'c', 'd'}, 0x18, {'w', 'i', 'd', 'g', 'e', 't', ' ', ' '}, ...
Is there a good C++ solution? A clever macro that will effectively let "abcd" be char[4] with no '\0' terminator?
Thanks, Charles
回答1:
You could use a macro that will do the job:
#define MACRO_GET_1(str, i) \
(sizeof(str) > (i) ? str[(i)] : 0)
#define MACRO_GET_4(str, i) \
MACRO_GET_1(str, i+0), \
MACRO_GET_1(str, i+1), \
MACRO_GET_1(str, i+2), \
MACRO_GET_1(str, i+3)
#define MACRO_GET_STR(str) MACRO_GET_4(str, 0)
struct mystruct {
char foo[4];
};
int main() {
mystruct obj{ MACRO_GET_STR("abcd") };
const char* str = "abcd";
std::cout << memcmp(obj.foo, str, 4); // 0
return 0;
}
Example
This code is based on this solution and it is also easily extendable.
Anyway there was a proposal some time ago that probably never made it to the standard. There are patches around that allow string literals to be converted into variadic char packs.
回答2:
Give the struct a constructor that accepts char arrays of size 1 greater than what you need, and ignore the terminating character when copying them over.
bar::bar(int, char const(&)[5], int, char const(&)[9], ...)
Or, you can just make the parameters char const*
and trust the user to pass correctly sized arrays, in accordance with your documentation. If you don't want to, or can't, add anything to the struct, then just create a function with those same arguments which returns one (RVO should eliminate extra copying).
回答3:
I think it will work as a uint8 array (or whatever your compiler supports). Just don't ever think it's a string, because it is not. It's MUCH safer the allocate an extra char and initialise to zero (usually automatic). It is better still to use STL components, unless there is a very good reason to do something else.
C++ is not C. In C++ the compiler tries to keep you safe. In C it is entirely your own lookout.
来源:https://stackoverflow.com/questions/26613420/how-readily-do-unterminated-char-arrays-in-c