Including files as raw string literals [duplicate] - c++

This question already has answers here:
"#include" a text file in a C program as a char[]
(21 answers)
Closed 9 years ago.
I have a C++ source file and a Python source file. I'd like the C++ source file to be able to use the contents of the Python source file as a big string literal. I could do something like this:
char* python_code = "
#include "script.py"
"
But that won't work because there need to be \'s at the end of each line. I could manually copy and paste in the contents of the Python code and surround each line with quotes and a terminating \n, but that's ugly. Even though the python source is going to effectively be compiled into my C++ app, I'd like to keep it in a separate file because it's more organized and works better with editors (emacs isn't smart enough to recognize that a C string literal is python code and switch to python mode while you're inside it).
Please don't suggest I use PyRun_File, that's what I'm trying to avoid in the first place ;)

The C/C++ preprocessor acts in units of tokens, and a string literal is a single token. As such, you can't intervene in the middle of a string literal like that.
You could preprocess script.py into something like:
"some code\n"
"some more code that will be appended\n"
and #include that, however. Or you can use xxd​ -i to generate a C static array ready for inclusion.

This won't get you all the way there, but it will get you pretty damn close.
Assuming script.py contains this:
print "The current CPU time in seconds is: ", time.clock()
First, wrap it up like this:
STRINGIFY(print "The current CPU time in seconds is: ", time.clock())
Then, just before you include it, do this:
#define STRINGIFY(x) #x
const char * script_py =
#include "script.py"
;
There's probably an even tighter answer than that, but I'm still searching.

The best way to do something like this is to include the file as a resource if your environment/toolset has that capability.
If not (like embedded systems, etc.), you can use a bin2c utility (something like http://stud3.tuwien.ac.at/~e0025274/bin2c/bin2c.c). It'll take a file's binary representation and spit out a C source file that includes an array of bytes initialized to that data. You might need to do some tweaking of the tool or the output file if you want the array to be '\0' terminated.
Incorporate running the bin2c utility into your makefile (or as a pre-build step of whatever you're using to drive your builds). Then just have the file compiled and linked with your application and you have your string (or whatever other image of the file) sitting in a chunk of memory represented by the array.
If you're including a text file as string, one thing you should be aware of is that the line endings might not match what functions expect - this might be another thing you'd want to add to the bin2c utility or you'll want to make sure your code handles whatever line endings are in the file properly. Maybe modify the bin2c utility to have a '-s' switch that indicates you want a text file incorportated as a string so line endings will be normalized and a zero byte will be at the end of the array.

You're going to have to do some of your own processing on the Python code, to deal with any double-quotes, backslashes, trigraphs, and possibly other things, that appear in it. You can at the same time turn newlines into \n (or backslash-escape them) and add the double-quotes on either end. The result will be a header file generated from the Python source file, which you can then #include. Use your build process to automate this, so that you can still edit the Python source as Python.

You could use Cog as part of your build process (to do the preprocessing and to embed the code). I admit that the result of this is probably not ideal, since then you end up seeing the code in both places. But any time I see the "Python," "C++", and "Preprocessor" in closs proximity, I feel it deserves a mention.

Here is how automate the conversion with cmd.exe
------ html2h.bat ------
#echo off
echo const char * html_page = "\
sed "/.*/ s/$/ \\n\\/" ../src/page.html | sed s/\"/\\\x22/g
echo.
echo ";
It was called like
cmd /c "..\Debug\html2h.bat" > "..\debug\src\html.h"
and attached to the code by
#include "../Debug/src/html.h"
printf("%s\n", html_page);
This is quite system-dependent approach but, as most of the people, I disliked the hex dump.

Use fopen, getline, and fclose.

Related

what is a string literal surrounded with # means in C++

I came across this in a source code:
#define DEFAULT_PATHNAME "#SDK_DEFAULT_PATHNAME#"
what does the # symbol denotes in this case ?
Edit:
Camke was used to generate this project.
This value is used as a path to a file
CMake has this wonderful command configure_file which allows your build system to generate a file used in the build where the content (i.e. value) of the variable SDK_DEFAULT_PATHNAME will be put in the location of #SDK_DEFAULT_PATHNAME# in the "configured file".
In this case it's part of the string, nothing special.
On Windows for example, you could have the following string:
#define DEFAULT_PATHNAME "%PATH_TO_SDK%"
with the % character playing the same role. In C++ and in strings in general, it has no meaning (unlike \ which is used to escape characters).
EDIT:
To clarify, esp. with regards to your comment:
that value is used as a path to a file for the program to open, when removing the # the program broke
The operating system may need to read this character, as I mentioned it with the % example on Windows, to consider the path as something to look up in the environment variables for example. Once again, it has no special meaning in C++ or strings in general, but may have for other programs.

Add/edit string in compiled C program?

I have a strange question, I am wondering if there is a way to add/edit a string (or something that could be accessed via the C program (inside, ie not an external file)) after it has been compiled?
The purpose is to change a URL on an Windows program via PHP on Linux (obviously I cannot just compile it).
Many posix platforms come with the program strings which will read through a binary file searching for strings. There is an option to print out the offset of the strings. For example:
strings -td myexec
From there you can use a hex editor but the main problem is that you wouldn't be able to make a string bigger than it already is.
A Hex Editor is probably your best bet.
A hex editor will work, but you have to be careful not to alter the size of the executable. If the string happens to be in the .res file, you can use ResEdit.
There are specialized tools to modify existing executable files. A notable tool is
Resource Tuner, which can be used to edit all sorts of resources in an executable.
Another option is to use a text editor, like Hex Workshop, to edit the characters in the strings of an executable. However, bear in mind that with this method, you can only edit existing strings in an executable, and the replaced strings must have an equal or smaller length than the original ones, otherwise you'll end up modifying executable code.
As others have suggested, you can use a binary file editor (hex editor) to change the string in the executable file. You will want to embed into the string a marker (unique sequence of bytes) so that you can find the string in your file. And you will want to ensure that you are reading/writing the file at correct offsets.
As OP stated plans to use PHP on linux to rewrite the file, you will need to use fseek to position the file pointer to the starting location of this URL string, ensure you stay within the size of the string as you replace bytes, and then use fseek/rewind and fwrite to change the file.
This technique can be used to change a URL embedded in a binary file, and it can also be used to embed a license key into a binary, or to embed an application checksum value into a binary so that one can detect when the binary has changed.
As some posters have suggested, you may need to recompute a checksum or re-sign a binary file. A quick way to check for this behavior would be to compile two versions of your binary with different URL values. Then compare the files and see if there are differences other than in the URL values.
to properly edit a string in a compiled program you need to:
read in the files bytes
search the .rdata for strings and record the address of the first occurrence of the string
convert that address to the virtual address using some of the data in the file header
write a new .rdata onto the executable and write your new string into it recording its address and getting its virtual address.
search the .text section for references to the virtual address of the old string and replace it with the reference to your new string.
fortunately i made a program to do this on windows it only works on 32 bit programs here
Not unless you want to poke around in the generated hex or assembly code.

Folder with 1300 png files into html images list

I've got folder with about 1300 png icons. What I need is html file with all of them inside like:
<img src="path-to-image.png" alt="file name without .png" id="file-name-without-.png" class="icon"/>
Its easy as hell but with that number of files its pure waste of time to do it manually. Have you any ideas how to automate it?
If you need it just once, then do a "dir" or "ls" and redirect it to a file, then use an editor with macro-ability like notepad++ to record modifying a single line like you desire, then hit play macro for the remainder of the file. If it's dynamic, use PHP.
I would not use C++ to do this. I would use vi, honestly, because running regular expressions repeatedly is all that is needed for this.
But young an do this in C++. I would start with a plan text file with all the file names generated by Dir or ls on the command prompt.
Then write code that takes a line of input and turns it into a line formatted the way you want. Test this and get it working on a single line first.
The RE engine of C++ is probably overkill (and is not all that well supported in compilers), but substr and basic find and replace is all you need. Is there a string library you are familiar with? std::string would do.
To generate the file name without PNG, check the last four characters and see if they exist and are .PNG (if not report an error). Then strip them. To remove dashes, copy characters to a new string but if you are reading a dash write a space. Everything else is just string concatenation.

Opening a file on unix using c++

I am trying to open a file in c++ and the server the progam in running on is based on tux.
string filename = "../dir/input.txt"; works but
string filename = "~jal/dir1/dir/input.txt"; fails
Is there any way to open a file in c++ when the filename provided is in the second format?
The ~jal expansion is performed by the shell (bash/csh/whatever), not by the system itself, so your program is trying to look into the folder named ~jal/, not /home/jal/.
I'm not a C coder, but getpwent() may be what you need.
You could scan the string, replacing ~user by the appropriate directory.
The POSIX function wordexp does that, and a few other things
variable substitution, like you can use $HOME
optional command substitution, like $(echo foo) (can be disabled)
arithmetic expansion, like $((3+4))
word splitting, like splitting ~/a ~/b into two words
wildcard expansion, like *.cpp
and quoting, like "~/a ~/b" remains that
Here is a ready piece of code, that performs this task:
How do I expand `~' in a filename like the shell does?

Incorporating text files in applications?

Is there anyway I can incorporate a pretty large text file (about 700KBs) into the program itself, so I don't have to ship the text files together in the application directory ? This is the first time I'm trying to do something like this, and I have no idea where to start from.
Help is greatly appreciated (:
Depending on the platform that you are on, you will more than likely be able to embed the file in a resource container of some kind.
If you are programming on the Windows platform, then you might want to look into resource files. You can find a basic intro here:
http://msdn.microsoft.com/en-us/library/y3sk7e6b.aspx
With more detailed information here:
http://msdn.microsoft.com/en-us/library/zabda143.aspx
Have a look at the xxd command and its -include option. You will get a buffer and a length variable in a C formatted file.
If you can figure out how to use a resource file, that would be the preferred method.
It wouldn't be hard to turn a text file into a file that can be compiled directly by your compiler. This might only work for small files - your compiler might have a limit on the size of a single string. If so, a tiny syntax change would make it an array of smaller strings that would work just fine.
You need to convert your file by adding a line at the top, enclosing each line within quotes, putting a newline character at the end of each line, escaping any quotes or backslashes in the text, and adding a semicolon at the end. You can write a program to do this, or it can easily be done in most editors.
This is my example document:
"Four score and seven years ago,"
can be found in the file c:\quotes\GettysburgAddress.txt
Convert it to:
static const char Text[] =
"This is my example document:\n"
"\"Four score and seven years ago,\"\n"
"can be found in the file c:\\quotes\\GettysburgAddress.txt\n"
;
This produces a variable Text which contains a single string with the entire contents of your file. It works because consecutive strings with nothing but whitespace between get concatenated into a single string.