Is there a way to pull a text resource into a string string literal using a preprocessor?

I just noticed that the answer I gave for this question does not actually work:

Regardless of whether CMake is used or not, the following should work with the current standard:

std::string resource = R"( #include "text.txt" )"; 

I thought the pre-processor would recognize the #include "text.txt" in the first place and expand the text.

But this is obviously not the case, the result for

 std::cout << resource << std::endl; 

there is

 #include "text.txt" 

I tried using some macro so that the #include statement was expanded internally, but it doesn’t work either:

 #include <string> #include <iostream> #define RESOURCE_DEFINIION(resource_var,resource_name) \ const std::string resource_var = R"xxx( \ #include resource_name \ )xxx"; RESOURCE_DEFINIION(resource,"text.txt") int main() { std::cout << resource << std::endl; return 0; } 

Output signal

 \ #include resource_name \ 

Here is a demo to play with


Are there any deceptive possibilities for attracting the text.txt resource to a literal with the source string C ++ - 11 using the preliminary processor or any other regular function of the C ++ language?


Denial of responsibility:

I know well what is wrong with the examples above and why they fail in this way. The problem is that the preprocessor ignores the material in pairs. "

So, is there a way to avoid this so that it can be seen in front of the processor?

+4
c ++ c-preprocessor c ++ 11 string-literals
source share
2 answers

It seems like this is not possible in standard C ++

Problem 0 : The standard method for text inclusion is the #include directive.

Problem 1 : A string literal is a preprocessing token that is recognized in phase 3, so when the preprocessing directives execute in phase 4, it has already been determined that #include is part of the literal string, not the preprocessing directive.

preprocessing marker:
Header name
identifier
C. number
character literal
user-defined literal characters
Literal string
user-defined string literal
Preprocess-op-or-punc
each non-white space character that cannot be one of the above

Problem 2 : it is impossible to bring the preprocessing directive to the source code and execute it using macro substitution:

16.3.4 / 3
The resulting fully macro-replaceable preprocessing token sequence is not processed as a preprocessing directive, even if it looks like

Thus, you cannot work inside #include inside a macro.

Problem 3 : the macro replacement list must be a valid preprocessing token:

Line control:
# define new-line replacement-list identifier
replacement list:
pp-tokens opt
C. tokens:
Marker Pretreatment
pp-tokens pre-processing token

And the string literal is the preprocessing token itself, you cannot create a string literal from several macros.

+4
source share

I think you just messed up the syntax; The following correctly assigns a string literal to the variable std :: string:

 #include <iostream> #include <string> int main() { std::string raw = // #include "text.txt" std::cout << raw << std::endl; return 0; } 

where text.txt:

 R"( ABC )"; 
-4
source share

All Articles