1

I'm working on a C++14 application where I want to assign the entire contents of a text file to a std::string, stringstream, or char variable or structure. This is easy at runtime, but I want this to happen at compile-time or from a compiler macro (before runtime).

I do not want to use a pre-compile step with a script, cmake tricks, etc..

The text file will have characters such as '#' and '/' as well as letters and digits. There are linefeed characters as well.

Is there a way to do this in C++14? I've looked through Boost and could not find a way to do this before runtime. Large amounts of web-searching has not given me any hope either.

If there's not a way to do this in C++14 but one exists in C++17, that would be useful to know also.

I've seen this solution for run-time assignment of a string (the accepted answer to this question: Read whole ASCII file into C++ std::string). I've tried to make the variable str a constexpr but that won't compile because the ifstream is not a constant :

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
             std::istreambuf_iterator<char>());

What I expect is to have the all of the characters in the file available in the string, stream, or character, with all of the files original characters (including the linefeed and other whitespace) in the same order as they occur in the file.

UPDATE:
Even incbin, as suggest in the comments, under MSVC (VS2015) requires a pre-compile step to process the file before adding it's binary form to the C++ application.

I've given up at this point and will use the following method:

1) process the file with a script to add the following string to the beginning of the file: R"(

2) have the script add the following to the end of the file: )"

3) use the following code to set a char variable:

constexpr char* const s1 =
#include "file.txt"
;

where file.txt is the modified file with the steps 1) and 2) above completed.

I can parse the data from that. I checked the output of a test program that uses the above code and sends the contents of s1 to the console to find all of the data, including the linefeeds. I also found the data in the .exe that VS2015 built.

The script that will do the work of steps 1) and 2) above will first check if R"( and )" are at the beginning and end of the file, respectively, before changing the file.

Thank you for the suggestions and the help!

alteredz
  • 11
  • 3
  • https://github.com/graphitemaster/incbin – tkausl Jan 15 '19 at 21:14
  • 2
    No, there's no way to do what you want without an external program to convert the file to valid C++ source. – Mark Ransom Jan 15 '19 at 21:19
  • What is the *real* problem you want to solve? Why do you want to read a file at compile-time? This has the smell of an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – Some programmer dude Jan 15 '19 at 21:21
  • @Someprogrammerdude it smells OK to me, I've needed to do the same in the past. Maybe the program will need to be distributed to a device that doesn't have the file for example. – Mark Ransom Jan 15 '19 at 21:24
  • As for possible way to solve it, do some research about *resource files*. If you're using Qt and its build-system, or are on Windows, then using resource files for such things is relatively easy. Otherwise the only solution is to preprocess the file to turn it into a source file containing the contents as a literal string that initializes a variable. – Some programmer dude Jan 15 '19 at 21:27
  • Check your build system manual. – balki Jan 15 '19 at 21:46
  • @Someprogrammerdude - not an XY problem. I tried and considered MANY solutions and only showed the one that was the closest to working (it works, it's just runtime). The reason is that the files are small, and if subsequent parsing fails it will only be because there was a problem with the actual reading of the files (the format of the files follow a standard which is easy to parse). I want that to occur BEFORE run-time. – alteredz Jan 15 '19 at 21:50
  • I've considered resource files. The problem is that this application is linked to different other applications on multiple OS's and platforms and I do not want to get involved in covering the setup of that on all of those combinations. Using VS2015 and gcc/make on multiple systems. – alteredz Jan 15 '19 at 21:52
  • @tkausl and someprogrammerdude: incbin looks promising, since I don't think there's any other way to do this (agreeing with Mark Ransom). I will have to get incbin installed for the places that use VS2015, but the other users are all on linux using gcc/make, so that should be seamless. – alteredz Jan 15 '19 at 22:12
  • I gave up and updated the question. – alteredz Jan 16 '19 at 05:10
  • It's an XY problem because you only tell us the solution, but never the problem the solution is supposed to solve. You say (in your comment) that you have tried many solutions, but together with the problem you should also mention more solutions you've tried since then we won't have to write answers using those tried solutions. But the most important thing about telling us the actual problem is that someone could more easily come up with a new solution that you haven't tried yet. – Some programmer dude Jan 16 '19 at 08:15
  • Lastly, please read about [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Jan 16 '19 at 08:15
  • @Someprogrammerdude. I DID state the problem I was trying to solve, in the very top 2 paragraphs of the question. I was very explicit on what I wanted to do. " I'm working on a C++14 application where I want to assign the entire contents of a text file to a std::string, stringstream, or char variable or structure. This is easy at runtime, but I want this to happen at compile-time or from a compiler macro (before runtime). I do not want to use a pre-compile step with a script, cmake tricks, etc.." – alteredz Jan 16 '19 at 20:31
  • That just states what you want to do, but doesn't say *why* you want to do it. What is the problem that is solved by "assign the entire contents of a text file to a std::string, stringstream, or char variable or structure"? You must want to do it for a *reason*, what is that reason? If it's just plain curiosity, then that's okay, but please *tell* us. That is what the XY problem is all about. – Some programmer dude Jan 17 '19 at 02:42

0 Answers0