I have a c# program and am trying to call a messageBox with a specific string(normal string, nothing special), And when reaching a variable to concatenate with the string, it apparently stops the concatenation.
The code:
string first = userInfo.info.getFirst(); //Some function
string last = userInfo.info.getLast(); // Some function
string message = first + "_" + last + " !";
MessageBox.Show(message);
// Output will be "(first value)";
I did try to debug and the values of "first" and "last" are correct and fine.
I also analyzed to see if any CPU or Memory peak occur(using VS's tools), but seen none.
Any idea as for the problem?
Thanks a lot!
The Win32 GUI libraries terminate strings if they find a \0 character (U+0000, Unicode "null") in them. For example, if you had:
MessageBox.Show("First part\0Second part");
then only First part would be displayed.
There are at least two options here:
Work out where the "bad" character is coming from. It's often a misuse of the Stream or TextReader API, not paying attention to how many bytes or characters are returned by a Read call
Just remove the "bad" character, e.g. message = message.Replace("\0", "");
The first option is preferable - I'd only resort to the second if I really couldn't get clean data.
Related
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);
I run a repeated Regex.Replace over a string, replacing certain "variables" with their "values". Thing is, some get replaced and some don't!
I have to analyze certain batch files (IBM JCL batch language, to be precise) and search them for JCL variables (rules: JCLvariable starts with "&" and ends with space; ","; "." or other variable start, that being "&"). My functions is supposed to take the string with variables and array of variables-and-their-values as an input; then search the string and replace JCL variables with their values. So is I run a forcycle and for each value-variable struct in array, I run Regex.Replace (in order to prevent the "&TOSP." being misplaced for "&TO." and adhere to JCL var rules, see above):
private string ReplaceDSNVarsWithValues(string _DSN,JCLvar[] VarsAndValues)
{
//FIXME: nefunguje pro TIPfile a nebere všechny &var
for(int Fa=0;Fa<VarsAndValues.Length/2;++Fa)
{
_DSN = Regex.Replace(_DSN, "&"+VarsAndValues[Fa].JCLvariable+"[^A-Za-z0-9]", VarsAndValues[Fa].JCLvalue);
}
return _DSN;
}
Eg. I have this as a string to replace:
string _DSN = "&TOSP..COPY.&SYSTEM..SP&APL..BVSIN.SAVEC.D&MES.&DEN..V&VER.K99";
And then I have an array of struct containing couples of variable and value, eg.
JCLvar[1].variable = "APL",JCLvar[1].value = "PROD"
Combine that and it should result in the "SP&APL." part changing to "SPPROD".
The problem is, only SOME of the variables get replaced:
&TOSP..COPY.&SYSTEM..SP&APL..BVSIN.SAVEC.D&MES.&DEN..V&VER.K99 gets changed to SP.COPY.DBA0.SPPROD.BVSIN.SAVEC.D&MESDENV&VER.K99 as it should (disregard &MES,&DEN - these are not filled in the ValsAnd Values array and therefore don't get replaced), but in
&TO..#ZDSK99.PODVYP.M&MES.U&DEN..SUC.RES, the "&TO." doesn't get changed at all - although it exists in the array and via debugging, I see that it is being passed to the regex /but it doesn't get changed/.
How the heck it comes SOME variables get replaced and others don't?
In the array VarsAndValues, order of variables matters, because if "TOSP" is first, it gets replaced and "&TO" does not, while if "TO" is first, it gets replaced and "&TOSP" doesn't; therefore, I got suspicion that Regex.Replace somehow fails to do repeated replace on similar expressions/variables in the same string OR fails to recognize the variable/expression to be replaced - but I see no reason for the first possibility and the second one is impossible, as the replaced expressions clearly stay there.
//Note - I know it's certainly not nice coding, but it's more a single-purpose script I wrote to save me weeks of manual work than anything else
I don't see anything wrong with your regex. But why are you iterating over only half of VarsAndValues?
for(int Fa=0;Fa<VarsAndValues.Length/2;++Fa)
tells me you're stopping halfway through the array, so if TOSP happens to fall in the second half, it won't be replaced.
I am working with a project that includes getting MMS from a mms-gateway and storing the image on disk.
This includes using a received base64encoded string and storing it as a zip to a web server. This zip is then opened, and the image is retrieved.
We have managed to store it as a zip file, but it is corrupted and cannot be opened.
The documentation from the gateway is pretty sparse, and we have only a php example to rely on. I think we have figured out how to "translate" most of it, except for the PHP function stripcslashes(inputvalue). Can anyone shed shed any light on how to do the same thing in c#?
We are thankful for any help!
stripcslashes() looks for "\x" type elements within longer strings (where 'x' could be any character, or perhaps, more than one). If the 'x' is not recognised as meaningful, it just removes the '\' but if it does recognise it as a valid C-style escape sequence (i.e. "\n" is newline; "\t" is tab, etc.), as I understand it, the recognised character is inserted instead: \t will be replaced by a tab character (0x09, I think) in your string.
I'm not aware of any simple way to get the .net framework to do the same thing without building a similar function yourself. This obviously isn't very hard, but you need to know which escape sequences to process.
If you happen to know (or find out by inspecting your base64 text) that the only thing in your input that will need processing is a particular one or two sequences (say, tab characters), it becomes very easy and the following snippet shows use of String.Replace():
string input = #"Some\thing"; // '#' means string stored without processing '\t'
Console.WriteLine(input);
string output = input.Replace(#"\t", "\t");
Console.WriteLine(output);
Of course, if you really do simply want to remove all the slashes:
string output = input.Replace(#"\", "");
Is there a decent way to declare a long single line string in C#, such that it isn't impossible to declare and/or view the string in an editor?
The options I'm aware of are:
1: Let it run. This is bad because because your string trails way off to the right of the screen, making a developer reading the message have to annoying scroll and read.
string s = "this is my really long string. this is my really long string. this is my really long string. this is my really long string. this is my really long string. this is my really long string. this is my really long string. this is my really long string. ";
2: #+newlines. This looks nice in code, but introduces newlines to the string. Furthermore, if you want it to look nice in code, not only do you get newlines, but you also get awkward spaces at the beginning of each line of the string.
string s = #"this is my really long string. this is my long string.
this line will be indented way too much in the UI.
This line looks silly in code. All of them suffer from newlines in the UI.";
3: "" + ... This works fine, but is super frustrating to type. If I need to add half a line's worth of text somewhere I have to update all kinds of +'s and move text all around.
string s = "this is my really long string. this is my long string. " +
"this will actually show up properly in the UI and looks " +
"pretty good in the editor, but is just a pain to type out " +
"and maintain";
4: string.format or string.concat. Basically the same as above, but without the plus signs. Has the same benefits and downsides.
Is there really no way to do this well?
There is a way. Put your very long string in resources. You can even put there long pieces of text because it's where the texts should be. Having them directly in code is a real bad practice.
If you really want this long string in the code, and you really don't want to type the end-quote-plus-begin-quote, then you can try something like this.
string longString = #"Some long string,
with multiple whitespace characters
(including newlines and carriage returns)
converted to a single space
by a regular expression replace.";
longString = Regex.Replace(longString, #"\s+", " ");
If using Visual Studio
Tools > Options > Text Editor > All Languages > Word Wrap
I'm sure any other text editor (including notepad) will be able to do this!
It depends on how the string is going to wind up being used. All the answers here are valid, but context is important. If long string "s" is going to be logged, it should be surrounded with a logging guard test, such as this Log4net example:
if (log.IsDebug) {
string s = "blah blah blah" +
// whatever concatenation you think looks the best can be used here,
// since it's guarded...
}
If the long string s is going to be displayed to a user, then Developer Art's answer is the best choice...those should be in resource file.
For other uses (generating SQL query strings, writing to files [but consider resources again for these], etc...), where you are concatenating more than just literals, consider StringBuilder as Wael Dalloul suggests, especially if your string might possibly wind up in a function that just may, at some date in the distant future, be called many many times in a time-critical application (All those invocations add up). I do this, for example, when building a SQL query where I have parameters that are variables.
Other than that, no, I don't know of anything that both looks pretty and is easy to type (though the word wrap suggestion is a nice idea, it may not translate well to diff tools, code print outs, or code review tools). Those are the breaks. (I personally use the plus-sign approach to make the line-wraps neat for our print outs and code reviews).
you can use StringBuilder like this:
StringBuilder str = new StringBuilder();
str.Append("this is my really long string. this is my long string. ");
str.Append("this is my really long string. this is my long string. ");
str.Append("this is my really long string. this is my long string. ");
str.Append("this is my really long string. this is my long string. ");
string s = str.ToString();
You can also use: Text files, resource file, Database and registry.
Does it have to be defined in the source file? Otherwise, define it in a resource or config file.
Personally I would read a string that big from a file perhaps an XML document.
You could use StringBuilder
For really long strings, I'd store it in XML (or a resource). For occasions where it makes sense to have it in the code, I use the multiline string concatenation with the + operator. The only place I can think of where I do this, though, is in my unit tests for code that reads and parses XML where I'm actually trying to avoid using an XML file for testing. Since it's a unit test I almost always want to have the string right there to refer to as well. In those cases I might segregate them all into a #region directive so I can show/hide it as needed.
I either just let it run, or use string.format and write the string in one line (the let it run method) but put each of the arguments in new line, which makes it either easier to read, or at least give the reader some idea what he can expect in the long string without reading it in detail.
Use the Project / Properties / Settings from the top menu of Visual Studio. Make the scope = "Application".
In the Value box you can enter very long strings and as a bonus line feeds are preserved. Then your code can refer to that string like this:
string sql = Properties.Settings.Default.xxxxxxxxxxxxx;
Can someone explain to me why my code:
string messageBody = "abc\n" + stringFromDatabaseProcedure;
where valueFromDatabaseProcedure is not a value from the SQL database entered as
'line1\nline2'
results in the string:
"abc\nline1\\nline2"
This has resulted in me scratching my head somewhat.
I am using ASP.NET 1.1.
To clarify,
I am creating string that I need to go into the body of an email on form submit.
I mention ASP.NET 1.1 as I do not get the same result using .NET 2.0 in a console app.
All I am doing is adding the strings and when I view the messageBody string I can see that it has escaped the value string.
Update
What is not helping me at all is that Outlook is not showing the \n in a text email correctly (unless you reply of forward it).
An online mail viewer (even the Exchange webmail) shows \n as a new line as it should.
I just did a quick test on a test NorthwindDb and put in some junk data with a \n in middle. I then queried the data back using straight up ADO.NET and what do you know, it does in fact escape the backslash for you automatically. It has nothing to do with the n it just sees the backslash and escapes it for you. In fact, I also put this into the db: foo"bar and when it came back in C# it was foo\"bar, it escaped that for me as well. My point is, it's trying to preserve the data as is on the SQL side, so it's escaping what it thinks it needs to escape. I haven't found a setting yet to turn that off, but if I do I'll let you know...
ASP.NET would use <br /> to make linebreaks. \n would work with Console Applications or Windows Forms applications. Are you outputting it to a webpage?
Method #1
string value = "line1<br />line2";
string messageBody = "abc<br />" + value;
If that doesn't work, try:
string value = "line1<br>line2";
string messageBody = "abc<br>" + value;
Method #2
Use System.Environment.NewLine:
string value = "line1"+ System.Environment.NewLine + "line2";
string messageBody = "abc" System.Environment.NewLine + value;
One of these ways is guaranteed to work. If you're outputting a string to a Webpage (or an email, or a form submit), you'd have to use one of the ways I mentioned. The \n will never work there.
You need to set a watch and see where exactly your database result string gets double escaped.
Adding two strings together will never double escape strings, so its either happening before that, or after that.
When I get the string out of the database, .NET escapes it automagically. However, the little # symbol is appended to the string, which I did not notice.
So it appeared to be non-escaped to my "about to go on holiday" eye inside the ide.
Therefore when the non-escaped \n was added to the string (as the whole string is no longer escaped), it would remove the # and show the database portion of the string escaped.
Gah, it was all an illusion.
Perhaps that holiday is overdue.
Thanks for your input.
If the actual string stored in the database is (spaces added for emphasis): "l i n e 1 \ n l i n e 2", then whatever stored it there probably has a bug. But assuming that is the exact string there, then the "abc\nline1\nline2" string is what happens when you look at the string which would print as "abcline1\nline2" in a debugger which escapes it (this is a convenience, allowing you to copy-paste out of the debugger straight into code without errors).
Short answer: .NET is not escaping the string, your debugger is. The code which writes a literal "\n" into the database has a bug.