How to disable the escape sequence in C++ - c++

I use C++ to process many files, and I have to write the file name in source code like this:
"F:\\somepath\\subpath\\myfile",
I wonder that if there's any way to get rid of typing "\\" to get a character '\' in string literal context, i.e, I hope I can just write "F:\somepath\subpath\myfile" instead the boring one.

Solutions:
use C++11 string literals: R"(F:\somepath\subpath\myfile)"
Use boost::path with forward slashes:
They will validate your path and raise exceptions for problems.
boost::filesystem::path p = "f:/somepath/subpath";
p /= "myfile";
just use forward slashes; Windows should understand them.

If you have C++11, you can use raw string literals:
std::string s = R"F:\somepath\subpath\myfile";
On the other hand, you can just use forward slashes for filesystem paths:
std::string s = "F:/somepath/subpath/myfile";

Two obvious options:
Windows understands forward slashes (or rather, it translates them to backslashes); use those instead.
C++11 has raw string literals. Stuff inside them doesn't need to be escaped.
R"(F:\somepath\subpath\myfile)"

Related

Why does it give me an error when opening a txt fiile? [duplicate]

I'm really confused about the escape character " \ " and its relation to the windows file system. In the following example:
char* fwdslash = "c:/myfolder/myfile.txt";
char* backslash = "c:\myfolder\myfile.txt";
char* dblbackslash = "c:\\myfolder\\myfile.txt";
std::ifstream file(fwdslash); // Works
std::ifstream file(dblbackslash); // Works
std::ifstream file(backslash); // Doesn't work
I get what you are doing here is escaping a special character so you can use it in this string. In no way by placing a backslash in a string literal or std::string do you actually change the string ---
---Edit: This is completely wrong, and the source of my confusion---
So it seems that the escape character is only treated by certain classes or things to mean something other than a backslash, like outputting on the console, ie., std::cout << "\hello"; will not print the backslash. In the case of ifstream (or I'm not sure if the same applies with the C fopen() version), it must be that this class or function treats backslashes as escape characters. I'm wondering, since the Windows file system uses backslashes wouldn't it make sense for it to accept the simple string with backslashes, ie., "c:\myfolder\myfile.txt" ? Trying it this way fails.
Also, in my compiler (Visual Studio) when I include headers I can use .\ and ..\ to mean either the current folder, or the parent folder. I'm pretty sure the \ in this isn't related to the escape character, but are these forms specific to Windows, part of the C preprocessor, or part of the C or C++ language? I know that backslashes are a Windows thing, so I can't see any reason another system would expect backslashes even when using .\ and ..\
Thanks.
In no way by placing a backslash in a string literal[...] do you
actually change the string
You do. Compiler actually modifies literal you wrote before embedding it into compiled program. If a backslash is found in string or character literal while parsing source code it is ignored and next character is treated specially. \n becomes carriage return, etc. For escaped characters without special meaning threatment is implementation defined. Usually it just means character unchanged.
You cannot just pass "c:\myfolder\file.txt" because it is not a string which will be seen by your program. Your program will see "c:myfolderfile.txt" instead. This is why escaped backslash has a special meaning, to allow embedding backslashes in actual string your program will see.
The solution is to either escape your backslashes, or use raw string literals (C++11 onwards):
const char* path = R"(c:\myfolder\file.txt)"
Filenames given to #include directive are not string literals, even if they are in form "path\to\header", so substitution rules are not applied to them.
The single backwards slash practically escapes the next character. In order to get rid of this behavior you need to double escape it. Now for the forward slash, it is probably a compatibility issue which follows the Unix tradition.
Similar thing to this is also in the Java world. A single forward slash is treated for path separation on both Windows and Unix, while also a double backslash.
To make it more clear why single backslash doesn't work, just remember that the following String practically produces a newline, a backslash and a tab:
"\n\\\t"
i.e. in an example like:
""c:\my\next\file.txt"
would actually produce:
"c:my
ext
ile.txt"
(the double space is form feed, see here)
Because when declaring a cstring literal the backslashes escape the next character, for special characters. This is so you can do newlines (\n), nulls (\0), carriage returns (\r) etc...
char* backslash = "c:\myfolder \myfile.txt";

c++, How to disable escape sequence in visual studio 2019? [duplicate]

For regular expression \w+\d, in many script language such as perl/python it can be written literally. But in C/C++, I must write it as:
const char *re_str = "\\w+\\d";
which is ugly to eye.
Is there any method to avoid it? MACRO are also acceptable.
Just as an FYI, the next C++ standard (C++ 0x) will have something called raw string literals which should let you do something like:
const char *re_str = R"(\w+\d)";
However until then I think you're stuck with the pain of doubling up your backslashes if you want the regex to be a literal in the source file.
When I reading [C: A reference manual] Chapter 3: Prepressors. An idea emerges:
#define STR(a) #a
#define R(var, re) static char var##_[] = STR(re);\
const char * var = ( var##_[ sizeof(var##_) - 2] = '\0', (var##_ + 1) );
R(re, "\w\d");
printf("Hello, world[%s]\n", re);
It's portable in both C and C++, only uses standard preprocessing features. The trick is to use macro to expand \ inside liternal string and then remove the leading and tailing double quote strings.
Now I think it's the best way until C++0x really introduce the new literal string syntax R"...". And for C I think it'll be the best way for a long time.
The side effect is that we cannot defined such a variable in the global scope in C. Because there's a statement to remove the tailing double-quote character. In C++ it's OK.
You can put your regexp in a file and read the file if you have a lot or need to modify them often. That's the only way I see to avoid backslashes.
No. There is only one kind of string literals in C++, and it's the kind that treats escaped characters.

Stripping characters of a wxString

I am working on an application written in C++ that primarily uses wxWidgets for its objects. Now, suppose I have the following wxString variable:
wxString path = "C:\\Program Files\\Some\\Path\\To\\A\\Directory\\";
Are there any ways to remove the trailing slashes? While wxString provides a Trim() method, it only applies to whitespace characters. I could think of converting the string to another string type and perform the stripping there and switch back to the wxString type (it is essential that I use the wxString type) but if there is a less convoluted way of doing things, I'd prefer that.
The others have mentioned how this can be achieved using wxString methods, however I would strongly advise using an appropriate class, i.e. either wxFileName or, maybe, std::filesystem::path, for working with paths instead of raw strings. E.g. to get a canonical representation of the path in your case I would use wxFileName::DirName(path).GetFullPath().
This is what I would use, if I had no proper path-parsing alternative:
wxString& remove_trailing_backslashes(wxString& path)
{
auto inb = path.find_last_not_of(L'\\');
if(inb != wxString::npos)
path.erase(inb + 1); //inb + 1 <= size(), valid for erase()
else //empty string or only backslashes
path.clear();
return path; //to allow chaining
}
Notes:
Unless you're doing something unusual, wxString stores wchar_ts internally, so it makes sense to use wide string and character literals (prefixed with L) to avoid unnecessary conversions.
Even in the unusual case when you'd have strings encoded in UTF-8, the code above still works, as \ is ASCII, so it cannot appear in the encoding of another code point (the L prefix wouldn't apply anymore in this case, of course).
Even if you're forced to use wxString, I suggest you try to use its std::basic_string-like interface whenever possible, instead of the wx-specific functions. The code above works fine if you replace wxString with std::wstring.
In support of what VZ. said in his answer, note that all these simplistic string-based solutions will strip C:\ to C:, and \ to the empty string, which may not be what you want. To avoid such issues, I would go for the Boost.Filesystem library, which is, as far as I know, the closest to the proposed standard library filesystem functionality (which is not formally part of the standard yet, but very close).
For completeness, here's what it would look like using Boost.Filesystem:
wxString remove_trailing_backslashes(const wxString& arg)
{
using boost::filesystem::path;
static const path dotp = L".";
path p = arg.wc_str();
if(p.filename() == dotp)
p.remove_filename();
return p.native();
}
It's not as efficient as the ad-hoc solution above, mainly because the string is not modified in-place, but more resilient to problems caused by special path formats.
path.erase(path.end() - 1);
or
path.RemoveLast();
My use case actually also considers scenarios without trailing slashes.
I came up with two solutions. The first makes use of regular expression:
wxRegEx StripRegex("(.+?)\\\\*$", wxRE_ADVANCED);
if (StripRegex.Matches(path))
{
path = StripRegex.GetMatch(path,1);
}
The second, as #catalin suggested, uses RemoveLast:
while (path.EndsWith("\\"))
{
path.RemoveLast();
}
Edit: Using #VZ's suggestion, I came up with the following:
// for some reason, the 'Program Files' part get's taken out in the resulting string
// so I have to first replace the double slashes
path.Replace("\\\\","\\");
path = wxFileName::DirName(path).GetPath();

How to exclude C++ raw string literals from syntax highlighting in Vim?

Quite honestly, raw string literals are a great addition to the C++ language. But (as expected) editors have a hard time to properly display those literals.
I am using Vim 7.4 and out-of-the-box raw string literals completely break the syntax highlighting. For example in
char const txt[] = R"(printf(")";
the 2nd '(' is highlighted red in vim.
Something like
char const txt2[] = R"( "{{" )";
breaks the highlighting of curly braces and the syntax based auto-ident - and so on.
For a start I would be happy to have Vim ignore everything between R"( and )" when doing syntax highlighting.
But note that raw string literals are flexible - arbitrary matching strings are allowed between the first/last double-quote/brace pair, e.g.
R"abcd()")")abcd"
is also a valid raw string literal which encodes
)")"
See also the cppreference link for a general definition of the syntax.
Thus my question how to configure Vim such that C++ raw string literals are properly recognized.
Vim already seems to include some facilities to properly synatx highlight language fragments embedded in a host language (e.g. for compiler-compiler source files). Perhaps they can be used for the raw string literal case as well?
Add this
syntax match cString 'R"\([^(]*\)(\_.*)\1"'
to your custom C++ syntax file (normally ~/.vim/syntax/cpp.vim ; create this file if you don't have one).
Just add cpp-vim as a plugin. I have added strict support for newer string literals in pull-request #14.
This is what you get: http://bl.ocks.org/anonymous/raw/9442865
cpp-vim adds support for other C++11 stuff too.
A tiny tweak on the above syntax rule:
syntax match cString 'R"\([^(]*\)(\_.\{-})\1"'
The original attempts to greedily select the longest match; so if you have multiple raw strings in a file (using the same open/close pattern) is would break.
This one is non-greedy, and should match correctly.
Thank you so much for the original though, it was a huge help to me!

How to avoid backslash escape when writing regular expression in C/C++

For regular expression \w+\d, in many script language such as perl/python it can be written literally. But in C/C++, I must write it as:
const char *re_str = "\\w+\\d";
which is ugly to eye.
Is there any method to avoid it? MACRO are also acceptable.
Just as an FYI, the next C++ standard (C++ 0x) will have something called raw string literals which should let you do something like:
const char *re_str = R"(\w+\d)";
However until then I think you're stuck with the pain of doubling up your backslashes if you want the regex to be a literal in the source file.
When I reading [C: A reference manual] Chapter 3: Prepressors. An idea emerges:
#define STR(a) #a
#define R(var, re) static char var##_[] = STR(re);\
const char * var = ( var##_[ sizeof(var##_) - 2] = '\0', (var##_ + 1) );
R(re, "\w\d");
printf("Hello, world[%s]\n", re);
It's portable in both C and C++, only uses standard preprocessing features. The trick is to use macro to expand \ inside liternal string and then remove the leading and tailing double quote strings.
Now I think it's the best way until C++0x really introduce the new literal string syntax R"...". And for C I think it'll be the best way for a long time.
The side effect is that we cannot defined such a variable in the global scope in C. Because there's a statement to remove the tailing double-quote character. In C++ it's OK.
You can put your regexp in a file and read the file if you have a lot or need to modify them often. That's the only way I see to avoid backslashes.
No. There is only one kind of string literals in C++, and it's the kind that treats escaped characters.