C# NewLine inside File.AppendAllText - c#

Writing a simple log for a program I'm doing and I'm getting troubles with FileAppendText()
I have this line to output various messages to the log:
File.AppendAllText( filePath, string.Format( "{0} {1}{2}", DateTime.Now, message, Environment.NewLine ) );
Problem with this is when I try to use it with a string like this
"This is my first line, \r\n this is my second line \r\n and this is my final line!"
It will just give this result
This is my first line, this is my second line and this is my final line!
when it should be
This is my first line,
this is my second line
and this is my final line!
Is there a way to fix this or do I have to do some dirty fixes?

File.AppendAllText does not modify the string that you pass in. You miust be misinterpreting what you are seeing.
Probably, the tool that you use to look at the file contents has a special way of showing them. It does not support rendering newlines. Use notepad.exe.
Maybe the question is based on wrong data. When you write line, \r\n this you should get two spaces. But your sample text does not have two spaces (line, this). Are you even showing us the exact thing you passed in and got out?!

I resolved the same problem using Environment.NewLine instead of \r\n.

Related

Check for carriage return\line feed in tab delimited text file in C#

I have what I believed to be new line feed\carriage return in tab delimited file that I am reading using C# Stream Reader, please see an extract below, the second and third lines is actually a single line that contains what I believed to be carriage return after "NL" on the second line. I have tried using the code below to determine the presence of new line\carriage return, but no luck.
Could someone please help?
Code extract
string line = sr.ReadLine();
if (line.EndsWith(Environment.NewLine))
{
MessageBox.Show("New line detected");
}
File extract
1224 TX68176 FR123 0.2241 2788848 JP31650 B62G7K6 J7618E108 8630
----------
1225 TX68176 NL
----------
128 0.2241 2788848 JP3165000 B62G7K6 J7618E108 8630
Because you are reading the line with ReadLine, you will never get an Environment.NewLine at the end of the line. Your real problem is that you have a line of data, which you are probably expecting to be a single line, split into multiple lines. The exception you are getting does not come from having an newline in the line you read, and you are not going to fix it by trying to detect a newline character.
The problem probably comes from the rest of your code expecting fields in the line that are not there, because this part of the code read a line of text data that was only a partial line of data. The rest of your code chokes on not getting all the fields in that data line. To detect that you have only a partial line of data, you will need to probably detect on line length, since it seems to be a fixed length formatted file, or detect on the number of fields after you split it with tabs.

Can't replace single whitespace with string.Replace()

I have run into a problem I do not understand. I am reading data from a file and have run into a situation where string.Replace(" ", "<whatever>") on an entry from the file will not replace the occurence of a single whitespace. I cannot help but to feel there is something very basic that I have missed, since the same kind of string declared as a literal works fine.
A typical line from the file (each entry is separated by a tab):
"2016-feb-08 09:54:00" "2016-feb-08 17:28:00" "Short" "227" "5 170,00" "+3,90%" "0,00"
The data from the file is read into an array using File.ReadAllLines().Split(new[] {"\t" }, StringSplitOptions.None);.
I then want to clean up the fifth entry for further processing, and this is when I run into the problem:
entries[4].Replace(" ", string.Empty).Replace("\"", string.Empty); gives "5 170,00"
Regex.Replace(entries[4], #"\s+", string.Empty).Replace("\"", string.Empty); gives "5170,00", which is the result I am looking for.
Running the first Replace() on a literal with a single space works fine, so I am curious if the whitespace inside the strings from the file are different somehow? And while the Regex solution works, I really want to know what my "issue" is.
You can use code like below to check hex values of the character. A normal space is 0x20 which the value showing between the five and the one in the code you posted.
string input = "2016-feb-08 09:54:00 2016-feb-08 17:28:00 Short 227 5 170,00 +3,90% 0,00";
byte[] output = Encoding.UTF8.GetBytes(input);

line break in alert popup

I am trying to add a new line Javascript alert message. I tried '\n' and 'Environment.NewLine'. I am getting Unterminated string constant error. Could you please let me know what could be the problem? I appreciate any help. I also tried \r\n.
string msg = "Your session will expire in 10 minutes. \n Please save your work to avoid this.";
if (!this.ClientScript.IsStartupScriptRegistered(ID))
this.ClientScript.RegisterStartupScript(GetType(), ID, String.Format("<script language=JavaScript>setTimeout(\'alert(\"{1}\");\',{0}*1000);</script>", sTime, msg));
I would suspect that you need to change your code to;
string msg = "Your session will expire in 10 minutes. \\n Please save your work to avoid this.";
And escape the \n otherwise your code outputted would actually include the line break rather than \n
Your output code would look like:
setTimeout('alert("Your Session....
Please save your work to ....");', 1000);
Rather than:
setTimeout('alert("Your Session....\n Please save your work to ....");', 1000);
I'm not sure, but I think that \n is escaped in the string.Format method, like \". Maybe you should use \\n instead.
Edited : and the first \ of \\n has been escaped when i posted that. xD
At first glance I would say the primary problem is that you're escaping the ' character around your alert. Since your string is defined by the double quotes, you don't need to escape this character.
add "#" at the beginning of your string - like this:
string msg = #"Your session ....";
The code looks fine, so I'm going to guess that you're using a message that itself has a ' quote in it, causing the JS syntax error. For inserting dynamic text into a Javascript code block, you really should use JSON to make your C# strings 'safe' for use in JS.
Consider JSON the go-to method for preventing the JS equivalent of SQL injection attacks.
Adding a # at the beginning should help.

Deleting line breaks in a text file with a condition

I have a text file. Some of the lines in it end with lf and some end with crlf. I only need to delete lfs and leave all crlfs.
Basically, my file looks like this
Mary had a lf
dog.crlf
She liked her lf
dog very much. crlf
I need it to be
Mary had a dog.crlf
She liked her dog very much.crlf
Now, I tried just deleting all lfs unconditionally, but then I couldn't figure out how to write it back into the text file. If I use File.WriteAllLines and put a string array into it, it automatically creates line breaks all over again. If I use File.WriteAllText, it just forms one single line.
So the question is - how do I take a text file like the first and make it look like the second? Thank you very much for your time.
BTW, I checked similar questions, but still have trouble figuring it out.
Use regex with a negative look-behind and only replace the \n not preceded by a \r:
DEMO
var result = Regex.Replace(sampleFileContent, #"(?<!\r)\n", String.Empty);
The (?<! ... ) is a negative look-behind. It means that we only want to replace instances of \n when there isn't a \r directly behind it.
Disclaimer: This may or may not be as viable an option depending on the size of your file(s). This is a good solution if you're not concerned with overhead or you're doing some quick fixes, but I'd look in to a more robust parser if the files are going to be huge.
This is an alternative to Brad Christie's answer, which doesn't use Regex.
String result = sampleFileContent.Replace("\r\n", "**newline**")
.Replace("\n","")
.Replace("**newline**","\r\n");
Here's a demo. Seems faster than the regex solution according to this site, but uses a bit more memory.
Just tested it:
string file = File.ReadAllText("test.txt");
file = file.Replace("\r", "");
File.WriteAllText("test_replaced.txt", file);

Spaces and backslashes in Visual Studio build events

I have an application that is supposed to aid my project in terms of pre- and post-build event handling. I'm using ndesk.options for command line argument parsing. Which gave me weird results when my project path contains spaces. I thought this was the fault of ndesk.options but I guess my own application is to blame. I call my application as a post-built event like so:
build.exe --in="$(ProjectDir)" --out="c:\out\"
A simple foreach over args[] displays the following:
--in=c:\my project" --out=c:\out"
What happened is that the last " in each parameter was treated as if it was escaped. Thus the trailing backslash was removed. And the whole thing is treated as a single argument.
Now I thought I was being smart by simply escaping the first " as well, like so:
build.exe --in=\"$(ProjectDir)" --out=\"c:\out\"
In that case the resulting args[] look like this:
--path="c:\my
project"
--out="c:\out"
The trailing backslash in the parameters is still swallowed and the first parameter is now split up.
Passing this args[] to ndesk.options will then yield wrong results.
How should the right command line look so that the correct elements end up in the correct args[] slots? Alternatively, how is one supposed to parse command line arguments like these with or without ndesk.options? Any suggestion is welcome.
Thanks in advance
Did you try to escape the last backslash?
build.exe --in="$(ProjectDir)\" --out="c:\out\\"
This works probably only, as long as the ProjectDir ends in \, which should be given.
This is just an idea, but I did not give it a try
EDIT:
I found a comment which suggests to leave out the trailing "
I actually used "." to solve this same problem:
build.exe --in="$(ProjectDir)." --out="c:\out\."
primarily because otherwise it might look like you are trying to escape the second quote...which you're not, you're escaping the final \ (which is hidden).
I also added a REM in the postbuild command describing why I did that.

Categories