Path/File name backslash in C# - c#

I'm converting from VB to C#, and in C# I seem not to be able to simply write a path string to the application settings..
D:\Something becomes D:\\Something
I tried also #"D:\Something", but that also doesn't work.
So what is the correct way? Say I want to have two settings; path and filename. How shall I format them, for the purpose of Path.Combine to make this a valid file-path/name for a database, or in other words, to have single backslashes?

Your code is working correctly - when you read a string with doubled slashes back, they becomes single slashes again. This is called escaping. It is designed to let you enter special characters as sequences starting in \. Single slash becomes special in this scheme, so you need to escape it with a slash as well.

Related

C# regex.escape unexpected behavior when processing "."

Hey I have an issue with Regex.Escape I'm trying to feed it an Email from TextBox Controll. The function recieves "test#test.test". What I expect to get is this "test#test\.test" Regex.Escape escapes the dot character. Hovever what I get instead is "test#test\\.test" which is very confusing. I plan on handing that string down to an SQL query and I'm worried abut users misbehaving.
holder.address = Regex.Escape(EmailAddressInput.Text);
This is how I assign resulting string to field in holder class.
I have been researching this problem on my own but most sources (including MSDN) suggest to prefix the dot ("the special character") with one backslash.
As it is right now backslash escapes backslash and result is a badly formatted email address.
var s = "test#test\\.test"; means the s holds the test#test\.test string. Your issue does not exist. There is a single backslash. Click the magnifier button on the right - you will see that in the Text Visualizer.
Regex has to have \\ because its escaping the \
the string itself actually only has one \ in it.

Properly escape filepaths

How do I escape with the #-sign when using variables?
File.Delete(#"c:\test"); // WORKS!
File.Delete(#path); // doesn't work :(
File.Delete(#"c:\test"+path); // WORKS
Anyone have any idea? It's the 2nd example I want to use!
Strings prefixed with # character are called verbatim string literals (whose contents do not need to be escaped).
Therefore, you can only use # with string literals, not string variables.
So, just File.Delete(path); will do, after you assign the path in advance of course (from a verbatim string or some other string).
Verbatim strings are just a syntactic nicety to be able to type strings containing backslashes (paths, regexes) easier. The declarations
string path = "C:\\test";
string path = #"C:\test";
are completely identical in their result. Both result in a string containing C:\test. Note that either option is just needed because the C# language treats \ in strings as special.
The # is not some magic pixie dust needed to make paths work properly, it has a defined meaning when prefixed to strings, in that the strings are interpreted without the usual \ escape sequences.
The reason your second example doesn't work like you expect is that # prefixed to a variable name does something different: It allows you to use reserved keywords as identifiers, so that you could use #class as an identifier, for example. For identifiers that don't clash with keywords the result is the same as without.
If you have a string variable containing a path, then you can usually assume that there is no escaping needed at all. After all it already is in a string. The things I mentioned above are needed to get text from source code correctly through the compiler into a string at runtime, because the compiler has different ideas. The string itself is just data that's always represented the same.
This still means that you have to initialise the string in a way that backslashes survive. If you read it from somewhere no special treatment should be necessary, if you have it as a constant string somewhere else in the code, then again, one of the options at the top has to be used.
string path = #"c:\test";
File.Delete(path);
This will work only on a string. The "real" string is "c:\\test".
Read more here.
There's a major problem with your understanding of the # indicator.
#"whatever string" is a literal string specifier verbatim string literal. What it does is tells the C# compiler to not look for escape sequences. Normally, "\" is an escape sequence in a string, and you can do things like "\n" to indicate a new line or "\t" to indicate a tab. However, if you have #"\n", it tells the compiler "no, I really want to treat the backslash as a backslash character, not an escape sequence."
If you don't like literal mode, the way to do it is to use "\\" anywhere you want a single backslash, because the compiler knows to treat an escaped backslash as the single character.
In either case, #"\n" and "\\n" will produce a 2-character string in memory, with the characters '\' and 'n'. It doesn't matter which way you get there; both are ways of telling the compiler you want those two characters.
In light of this, #path makes no sense, because you don't have any literal characters - just a variable. By the time you have the variable, you already have the characters you want in memory. It does compile ok, as explained by Joey, but it's not logically what you're looking for.
If you're looking for a way to get rid of occurrences of \\ within a variable, you simply want String.Replace:
string ugly = #"C:\\foo";
ugly = ugly.Replace(#"\\", #"\");
First and third are actual paths hence would work.
Second would not even compile and would work if
string path = #"c:\test";
File.Delete(path);

Do I need to escape backslash in a config file?

I have a config file, myapp.exe.config.
In the file I have an attribute with a fullpath filename as the value.
<add key="InfoFile" value="c:\temp\info.txt" />
It seems to work if I use a single or double backslash. That is,
<add key="InfoFile" value="c:\\temp\\info.txt" />
works also. What is the correct way to do this?
You don't need that. Anything within an attribute value is character data.
Since you're reading these values using C#, they'll get escaped as if they would be a literal path string in code.
Anyway, you might want to know that C# has # operator to declare verbatim strings, meaning that you don't need to escape backslashes when using literal paths in code:
string somePath = #"C:\blah\blih\bluh.txt";
A backslash has no special meaning in XML, so they should not be escaped.
Besides, if you would escape the backslashes in XML you would not use \\, you would use \.
The reason that it works with double backslashes also is that the file system is forgiving. You can use the path c:\\temp\\info.txt to reach the file c:\temp\info.txt.
Basically URL or URI holds single slash \ so, its better to use single slash. The problem comes while writing code, but in XML there is no problem to use single slash.
I think the best would to prevent the double backslash just in case, but if it works why change it. Maybe replace "\\" with "\" when you read the config value into your application.

Removing String Escape Codes

My program outputs strings like "Wzyryrff}av{v5~fvzu: Bb``igbuz~+\177Ql\027}C5]{H5LqL{" and the problem is the escape codes (\\\ instead of \, \177 instead of the character, etc.)
I need a way to unescape the string of all escape codes (mainly just the \\\ and octal \027 types). Is there something that already does this?
Thanks
Reference: http://www.tailrecursive.org/postscript/escapes.html
The strings are an encrypted value and I need to decrypt them, but I'm getting the wrong values since the strings are escaped
It sounds more like it's encoded rather than simply escaped (if \177 is really a character). So, try decoding it.
There is nothing built in to do exactly this kind of escaping.
You will need to parse and replace these sequences yourself.
The \xxx octal escapes can be found with a RegEx (\\\d{3}), iterating over the matches will allow you to parse out the octal part and get the replacement character for it (then a simple replace will do).
The others appear to be simple to replace with string.Replace.
If the string is encrypted then you probably need to treat it as binary and not text. You need to know how it is encoded and decode it accordingly. The fact that you can view it as text is incidental.
If you want to replace specific contents you can just use the .Replace() method.
i.e. myInput.Replace("\\", #"\")
I am not sure why the "\" is a problem for you. If it its actually an escape code then it just should be fine since the \ represents the \ in a string.
What is the reason you need to "remove" the escape codes?

string replace on escape characters

Today I found out that putting strings in a resource file will cause them to be treated as literals, i.e putting "Text for first line \n Text for second line" will cause the escape character itself to become escaped, and so what's stored is "Text for first line \n Text for second line" - and then these come out in the display, instead of my carriage returns and tabs
So what I'd like to do is use string.replace to turn \\ into \ - this doesn't seem to work.
s.Replace("\\\\", "\\");
doesn't change the string at all because the string thinks there's only 1 backslash
s.Replace("\\", "");
replaces all the double quotes and leaves me with just n instead of \n
also, using # and half as many \ chars or the Regex.Replace method give the same result
anyone know of a good way to do this without looping through character by character?
Since \n is actually a single character, you cannot acheive this by simply replacing the backslashes in the string. You will need to replace each pair of \ and the following character with the escaped character, like:
s.Replace("\\n", "\n");
s.Replace("\\t", "\t");
etc
You'd be better served adjusting the resx files themselves. Line breaks can be entered via two mechanisms: You can edit the resx file as XML (right-click in Solution Explorer, choose "Open As," and choose XML), or you can do it in the designer.
If you do it in the XML, simply hit Enter, backspace to the beginning of the newline you've created, and you're done. You could do this with Search and Replace, as well, though it will be tricky.
If you use the GUI resx editor, holding down SHIFT while pressing ENTER will give you a line break.
You could do the run-time replacement thing, but as you are discovering, it's tricky to get going -- and in my mind constitutes a code smell. (You can also make a performance argument, but that would depend on how often string resources are called and the scale of your app in general.)
I'm actually going with John's solution and editing the XML directly as that's the better solution for the project, but codelogic answered the question that was driving me insane.

Categories