Escaping double quotes within String.Format in C# - c#

I am attempting to get the 'Id' property of the Parameter element to be enclosed in double quotes. I first attempted to simply escape the quotations and this is the first thing I tried to achieve this:
buffer = String.Format("{0}" + "<Parameter Id=" + "{1}" + ">" + "{2}" + "</Parameter>", buffer, id, param);
With the above code I get this back, as you can see the escape characters are showing up, along with the quotation:
<Conquest><User>ArchElf</User><Token>0123456789012345678901234567890</Token><Command>validate</Command><Parameter Id=\"1\">Gemstone3</Parameter>
My second attempt is based on advised I received on IRC, a fellow advised that I may be able to use '"' to get my quotations, ala:
buffer = String.Format("{0}" + "<Parameter Id=" + """ + "{1}" + """ + ">" + "{2}" + "</Parameter>", buffer, id, param);
This method only yielded the literal '"' string in the end result:
<Conquest><User>ArchElf</User><Token>0123456789012345678901234567890</Token><Command>validate</Command><Parameter Id="1">Gemstone3</Parameter>
In desperation I went ahead and just added the literal double quotes baked into the string.
I did this because I read at This Codeproject Article that the only characters in a String.Format that I need to worry about escaping are curly braces and(surprise, surprise) this isn't even compile-able, WITH and WITHOUT the preceding #. Shouting at me a bunch of errors including:
Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
; Expected
) Expected
...and so on
Any help on this matter would be greatly appreciated. I know this has got to be something trivial I am missing, the best kind of conundrums. :/
Here is the entire BuildCommand method:
public string BuildCommand(string _command, string[] _parameters = null)
{
int id = 1;
string buffer = String.Format("<Conquest><User>"+"{0}"+"</User><Token>"+"{1}"+"</Token><Command>"+"{2}"+"</Command>", _playerName, _token, _command);
if (_parameters != null)
{
foreach (string param in _parameters)
{
if (param.Length < 1 || param == null)
break;
buffer = String.Format("{0}" + "<Parameter Id=" + "{1}" + ">" + "{2}" + "</Parameter>", buffer, id, param);
// buffer = String.Format(#"""{0}""<Parameter Id=""{1}"">""{2}""</Parameter>", buffer, id, param);
id += 1;
}
}

You could do it the right way
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//<Conquest><User>ArchElf</User><Token>0123456789012345678901234567890</Token><Command>validate</Command><Parameter Id=\"1\">Gemstone3</Parameter>
string user = "ArchElf";
string token = "0123456789012345678901234567890";
string command = "validate";
int id = 1;
string value = "Gemstrone3";
XElement conquest = new XElement("Conquest");
conquest.Add(new XElement("User", user));
conquest.Add(new XElement("Token", token));
conquest.Add(new XElement("Command", command));
XElement e_parameter = new XElement("Parameter", value);
e_parameter.Add(new XAttribute("Id", id));
conquest.Add(e_parameter);
}
}
}
​

You have to escape " with \:
String.Format("\"{0}\"<Parameter Id=\"{1}\">\"{2}\"</Parameter>", buffer, id, param);
You could also use a verbatim string literal, then you have to use double quotes:
String.Format(#"""{0}""<Parameter Id=""{1}"">""{2}""</Parameter>", buffer, id, param);

Related

String concatenation modifies double number when '|' is included

I cannot understand why this code is behaving like this. I have to return a string on a specific format. It looks like when I include the "|" character on the string, the numbers that come after it get modified.
Why would this happen? Is "|" somehow converting the double values again?
static int Main(string[] args) {
.........
connectionString = connectionString.Replace("'master'", databaseName);
var watch = System.Diagnostics.Stopwatch.StartNew();
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
}
watch.Stop();
string spentTimeString = String.Format("{0:0.##}", watch.ElapsedMilliseconds / 1000f);
string msg = $"Connection Time " + spentTimeString + "s.";
string perfData = "'connection_time'=" + String.Format("{0:0.##}", watch.ElapsedMilliseconds / 1000f);
string result = Ok(msg, perfData);
......
}
public static string Ok(string message, string perfData)
{
Console.WriteLine($"Msg: {message}");
Console.WriteLine($"PerfData: {perfData}");
string result = string.Concat("OK: ", message, "|", perfData);
Console.WriteLine($"Result: {result}");
return result;
}
Here is the Console output that I see:
Msg: Connection Time 0.42s.
PerfData: 'connection_time'=0.42
Result: OK: Connection Time 0.42s.|'connection_time'=0.41999
You can clearly see how 0.42 get's converted to 0.41999 after the concatenation takes place. How do I fix this?
I'm closing this post for now since it does not seem to be an issue with c#. It looks like NSClient++ is changing this value after it is returned.
I'm not sure though, I will post it on the proper section.
Thank you all!.

Parsing a list of values with option to empty list

I'm trying to parse an array of items, using Sprache library for C# I have a working code that goes like this.
public static Parser<string> Array =
from open in OpenBrackets.Named("open bracket")
from items in Literal.Or(Identifier).Or(Array).DelimitedBy(Comma).Optional()
from close in CloseBrackets.Named("close bracket")
select open + (items.IsDefined ? string.Join(", ", items.Get()) : " ") + close;
where "Literal" is a parser for numbers or strings, "Identifier" is a parser for a variable identifier and "Comma" is a parser for a comma token. But if I want the array to allow being empty "[ ]" I need to add the Optional() property and verify if "items" is defined:
select open + (items.IsDefined ? string.Join(", ", items.Get()) : " ") + close;
Is there a better cleaner way to do this for parsing a list of items separated by a separator char, that can be empty (list). That I can reuse with other lists of items.
Sample of input data structure:
[Literal/Identifier/Array] => Value;
[Value] [,Value]* => Array
[public/private] [identifier]; => Declaration;
[public/private] [identifier] [[=] [Value]] => Initialization;
A little cleaner way can be accomplished by GetOrElse method.
select open + string.Join(", ", items.GetOrElse(new string[0])) + close;
Try using Regex as in code below :
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.txt";
static void Main(string[] args)
{
StreamReader reader = new StreamReader(FILENAME);
string pattern = #"\[(?'bracketData'[^\]]+)\](?'repeat'[*+])?";
string line = "";
while ((line = reader.ReadLine()) != null)
{
line = line.Trim();
if (line.Length > 0)
{
string suffix = line.Split(new string[] {"=>"}, StringSplitOptions.None).Select(x => x.Trim()).Last();
MatchCollection matches = Regex.Matches(line, pattern);
var brackets = matches.Cast<Match>().Select(x => new { bracket = x.Groups["bracketData"].Value, repeat = x.Groups["repeat"].Value }).ToArray();
Console.WriteLine("Brackets : '{0}'; Suffix : '{1}'", string.Join(",", brackets.Select(x => "(" + x.bracket + ")" + x.repeat )), suffix);
}
}
Console.ReadLine();
}
}
}

Using \n correctly?

My code searches through a list and then if it finds a match, it displays the object in my listbox. My problem is that if there is more than 1 object in the list (if im searching for Alex and there is two objects with the name Alex), it returns it all on the same line instead of separating them to separate lines.
I coulda swore match += request + "\n"; was how to do it correctly, but it's not working.
Edit: One thing I dont understand is that if i just have match += request; it will allow me to use the horizontal scroll bar on my listbox to see everything written. And if i use match += request + "\n"; or match += request + Environment.NewLine; it doesn't let me use the scroll box and just cuts off.
public string SearchRequest(string keyword)
{
bool found = false;
string noMatch = "No requests with the name " + "'" + keyword + "'" + " were found";
string match = "";
foreach (ServiceRequest request in Requests)
{
if (request.searchKeywords(keyword))
{
match += request + "\n";
found = true;
}
}
if (found)
return match;
else
return noMatch;
}
/
public bool searchKeywords(string keyword)
{
if (keyword == name)
return true;
else
return false;
}
/
private void btnSearch_Click(object sender, EventArgs e)
{
lstSearch.Items.Clear();
lstSearch.Items.Add(myRequest.SearchRequest(txtSearch.Text));
}
Try
match += request + Environment.NewLine;
If you put all the results in a single string then it will still be a single item in the list.
Return an array of strings from the method instead of a single string:
public string[] SearchRequest(string keyword) {
List<string> match = new List<string>();
foreach (ServiceRequest request in Requests) {
if (request.searchKeywords(keyword)) {
match.Add(request.ToString());
}
}
if (match.Count > 0) {
return match.ToArray();
} else {
return new string[] { "No requests with the name " + "'" + keyword + "'" + " were found" };
}
}
Then use AddRange to add the strings as separate items in the list:
lstSearch.Items.AddRange(myRequest.SearchRequest(txtSearch.Text));
In Windows OS, the new line is two characters, the Carriage Return \r followed by Line Feed: \n. You can use Environment.NewLine as a shortcut (preferred) or append "\r\n" yourself. See further wikipedia entry on newline
Use one of these:
match += request + "\r\n";
Use an string literal:
match += request + #"
";
OR only at runtime will this resolve:
match += request + System.Environment.NewLine;
On Unix "\n"
You can't add a string with newlines to a listbox and expect it to show up as multiple items. Either split the string on newline and add each line separately to the listbox, or return a list of strings from your search function to begin with, avoiding the need for a split afterwards.

How to escape apostrophe when displaying inside a ASP.NET label

I have the following function which truncates a SQL Server varchar column and adds it to a string:
public void Pp()
{
strSql = #""; //query
using (SqlConnection conn = new SqlConnection(gstr))
{
try
{
SqlDataAdapter da = new SqlDataAdapter(strSql, conn);
myDataSet = new DataSet();
da.Fill(myDataSet);
string specific = "";
string generic = "";
string strTemp = "";
foreach (DataRow r in myDataSet.Tables[0].Rows)
{
if (r["MessageText"].ToString().Length <= 65)
{
strTemp = r["MessageText"].ToString();
}
else
{
strTemp = TruncateLongString(r["MessageText"].ToString(), 65);
}
specific += "</b><span class='hoverText' title='" + r["MessageText"] + "'>" + strTemp + "...</span>";
strTemp = "";
}
lblMessage.Text = "<b>SPECIFIC MESSAGES:</b> <br />" + specific;
}
catch (Exception ce)
{
}
}
}
public string TruncateLongString(string str, int maxLength)
{
return str.Substring(0, maxLength);
}
If the r["MessageText"] contains an appostrophe, it cuts off anything after it. (full text: no way no way HERE we go again but this is not working. Is it? or Is it not? I can't be too sure though. Can someone please check.)
Here is an example of a live preview (the title is shown but gets cut off because of the apostrophe):
Here is the source (the apostrophe is shown in the purple box. Also the color coding gets out of whack due to the apostrophe, which means the code is not correct):
How can I ensure it doesn't escape any escape characters, e.g. ', /, \.
You need to encode the HTML first.
Call this.Server.HtmlEncode( str ). This will also protect against other special characters like & and <.
That said, you're using single-quotes for attribute delimiters but HtmlEncode only encodes double-quotes, so you need to change your code to this:
specific = String.Format( CultureInfo.InvariantCulture, #"</b><span class=""hoverText"" title=""" + this.Server.HtmlEncode( r["MessageText"] ) + """>" + strTemp + #"...</span>";
.Replace(" ' ", "\\' "); You will probably want to do the same with double quote as well.

c# Searching for a string that contains quotes

I am fairly new to c# and am working on a little project but got stuck on this. I have a file that contains some assembly code. I want my program to search this file for a string, actually a value right after my string. One of the strings i am searching for is:
setproperty QName(PackageNamespace(""), "font")
getlocal 4
pushint
My search code is this:
private void searchFile(String searchText)
{
System.IO.StreamReader reader = new System.IO.StreamReader(file);
String text = reader.ReadToEnd();
if (Regex.IsMatch(text, searchText))
{
MessageBox.Show(searchText + " was found in the given file", "Finally!!");
}
else
{
MessageBox.Show("Sorry, but " + searchText + " could not be found in the given file", "No Results");
}
}
//when i click a button//
searchFile(#"setproperty QName(PackageNamespace(""""), ""font"")
getlocal 4
pushint ");
I know that the string is in the file but the result comes up with not found. I don't know if it is the quotes or tabs or both that is causing this.
Here is part of the file:
getlocal 4
pushstring "Verdana"
setproperty QName(PackageNamespace(""), "font")
getlocal 4
pushint 16764170
setproperty QName(PackageNamespace(""), "color")
getlocal 4
pushbyte 12
setproperty QName(PackageNamespace(""), "size")
My second question is how can i get the value of the first int after my search result?
Thanks in advance.
-Leen
You should change your method like this:
private static string searchFile(String searchText)
{
System.IO.StreamReader reader = new System.IO.StreamReader("test.txt");
String text = reader.ReadToEnd();
int poz = text.IndexOf(searchText);
if (poz >= 0)
{
int start = poz + searchText.Length;
int end = text.IndexOf("\n", start);
Console.WriteLine(searchText + " was found in the given file", "Finally!!");
return text.Substring(start, end - start);
}
else
{
Console.WriteLine("Sorry, but " + searchText + " could not be found in the given file", "No Results");
return string.Empty;
}
}
The call:
string val = searchFile("setproperty QName(PackageNamespace(\"\"), \"font\")\r\n\r\n getlocal 4\r\n pushint ");
So I think you may be use to VB.net. C-based languages (like c#) used the backslash character "\" as an escape character.
So in a searching for a double-quote in a string you would need to escape it using \".
I believe what you're looking for is:
searchFile(#"setproperty QName(PackageNamespace(\"\"), \"font\")
getlocal 4
pushint ");
But this isn't really a regular expression, which is what the Regex class is meant for. So I would (well not really, I would clean it up a bit, like not mix my UI and bizlogic) do this:
// Added String as the function type so you can return the matched "Integer" as a string, you could always do a Int32.TryParse(...)
private String searchFile(String file, String searchText)
{
System.IO.StreamReader reader = new System.IO.StreamReader(file);
String text = reader.ReadToEnd();
int32 index = text.IndexOf(searchText);
if (index >= 0) //We could find it at the very beginning
{
MessageBox.Show(searchText + " was found in the given file", "Finally!!");
int32 start = index + searchText.Length;
int32 end = Regex.Match(text, "[\n\r\t]", index).Index; // This will search for whitespace
String value = text.Substring(start, end - start);
// Now you can do something with your value, like...
return value;
}
else
{
MessageBox.Show("Sorry, but " + searchText + " could not be found in the given file", "No Results");
return "";
}
}

Categories