what is a string literal surrounded with # means in C++ - 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.

Related

Program to Create and Move a Pathname with more than 260 characters in Windows

The aim is to code a utility in C++ using the function:
BOOL WINAPI CreateDirectoryW(_In_ LPCTSTR lpPathName, _In_opt_LPSECURITY_ATTRIBUTES lpSecurityAttributes)
The only successful attempt found so far appears to be a in a Perl script, but getting that to work is another question. This script trials the prefix
my $path = '\\\\?\\'
but it has been observed elsewhere that using "\\?\UNC\" is more reliable.
Any code blocks would be welcome.
Edit: Also, as the original question title indicated, the problem is moving the folder to another location (other than a relative path). Can this path be moved with MoveFileEx?
The following is from the MSDN documentation on the CreateDirectory function.
There is a default string size limit for paths of 248 characters. This limit is related to how the CreateDirectory function parses paths.
To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\?\" to the path. For more information, see Naming a File.
Note that in C++, as in Perl, it is necessary to escape the \ characters in the source code unless you use Raw String Literals. Thus it would be
"\\?\"
in the source code.
Here is a quick example of how to do it.
BOOL CreatDirWithVeryLongName()
{
BOOL ret = ::CreateDirectoryW(L"\\\\?\\C:\\This is an example directory that has an extreemly long name that is more than 248 characters in length to serve as an example of how to go beyond the normal limit - Note that you will not be able to see it in Windows Explorer due to the fact that it is limited to displaying files with fewer than 260 characters in the name", NULL);
return ret;
}
This creates and deletes nested long paths, but does not move them.
Moving essentially implies creating a new tree where the main coding challenge is dealing with paths that have different permissions or attributes.

QSettings - What is the way to read path value?

Using windows xp, i want to read a value from .ini file.
The value is a path.
Using QSettings, the result of the call to "settings.value("key").toString()" is the the path excluding backslashes, because backslash is escape character.
What is the way to read a path from ini file, using QSettings?
Although backslash is a special character in INI files, most Windows applications don't escape backslashes () in file paths [...]
QSettings always treats backslash as a special character and provides no API for reading or writing such entries.
This is what the documentation has to say about it. It is a polite way of saying "if some other code does it, they're not following the WINAPI spec and it's broken and we shouldn't have to deal with it". Pretty much your .ini files are broken.
If you wish to read them, you may need to provide your own backend for QSettings. Such a backend can be easily obtained by copying the one that comes as part of Qt, and modifying it not to perform escaping.
You'd need to investigate whether writing your own QTextCodec for this purpose and passing it to QSettings::setIniCodec would be sufficient. If sufficient, you wouldn't need to provide an entire backend.
To minimize compatibility issues, any # that doesn't appear at the first position in the value or that isn't followed by a Qt type (Point, Rect, Size, etc.) is treated as a normal character.
Although backslash is a special character in INI files, most Windows applications don't escape backslashes () in file paths
enter link description here

Including files as raw string literals [duplicate]

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.

white space free path to My Documents

In building a C++ project with the GNU tool chain, make tells me ~
src/Adapter_FS5HyDE.d:1: *** multiple target patterns. Stop.
Search, search, search, and I found out that make thinks that it has multiple targets because the path to my included headers has spaces in it. If you've got your headers stored in some sane place like C:\Program Files then you can take care of this by using the old DOS paths (e.g. C:\PROGRA~1). However, when you have your headers in a truly insane place like My Documents you can get around the problem with MY DOC~1 because there's still a space.
Any idea how to tell my compiler to look in My Documents for headers without make confusing the path as two objects?
(Note: Feel free to throw tomatoes at me for putting header files in My Documents if you'd like, but there is a little rationale for doing that which I don't feel like explaining. If the solution to this question is easy, I'd rather keep it the way it is.)
You can figure out what the old path is by doing a DIR /X in your command prompt.
Or, most of the time you can fake it with the first 6 characters - spaces + ~1 + extension (8.3 paths won't have spaces).
Or, you can use quotes: "C:\Documents and Settings\Administrator\My Documents".
I don't know about make specficially, but the normal way around this is to put quotes around the path i.e.
cd "C:\Program Files\"
does that work?
Side note: the short name (8.3) for the same folder might not be the same on different OS installations. Thus, you can't be sure that C:\Program Files will always be C:\PROGRA~1.
Short names can't contain spaces in them either, so the usual short name for My Documents is MYDOCU~1, not MY DOC~1.
You can find the exact short name for any folder or file (including My Documents) using dir /x <filename>.
If you are using the GNU toolchain from Windows command line (cmd.exe), you should be able to use quotes (") around the folder/file names to work around this problem.
For some folders, including My Documents, you can specify an alternative location. To do this, right-click the folder, select Properties, select Location tab, and away you go. I use this to put my downloads and music on another drive (D:).
Write a wrapper script (e.g. batchfile) to translate the path names to short form.
I have a script "runwin" that does stuff like this - instead of, e.g. gcc <args> I can call runwin gcc <args>;
runwin will make heuristic guesses as to which arguments are filename paths and translate them, then call gcc on the resulting string of arguments.

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.