How can I insert a blank space (" "), when I concatenate a string? - c#

This question is for C Sharp (and Java maybe :).
When I want to display a message to the console, I want to insert after each "+" a blank space. How can I do this, without inserting manually that blank space?

try this
var text = string.Join(" ", new[] {foo, bar, other });

You can't, really - just put it in explicitly:
Console.WriteLine(foo + " " + bar);
or
System.out.println(foo + " " + bar);
I mean you could write a method with a parameter array / varargs parameter, e.g. (C#)
public void WriteToConsole(params object[] values)
{
string separator = "";
foreach (object value in values)
{
Console.Write(separator);
separator = " ";
Console.Write(value);
}
}
... but personally I wouldn't.

if you're looking for a way to tidy your printing routine try String.Format e.g.
Console.WriteLine(String.Format("{0} {1}", string1, string2));

In C#:
string.Join(" ", "Foo", "Bar", "Baz");
In Java:
String.join(" ", "Foo", "Bar", "Baz");
Each of these methods permits a variable number of strings to join, and each has various overloads to pass in collections of strings too.

You can replace "+" with "+ ". Something like this:
new String("Foo+Bar").replace("+", "+ ");

Do you mean a concatenation of strings or just a '+' character? In Java, if there are lot of parameters to show within an output string you can use String.format method like this: String.format("First: %s, second: %s, third: %s etc", param1, param2, param3). In my opinion it's more readable than chained concatenation with '+' operator.

In C# you can use String Interpolation as well using the $ special character, which identifies a string literal as an interpolated string
string text1 = "Hello";
string text2 = "World!";
Console.WriteLine($"{text1}, {text2}");
Output
Hello, World!
From Docs
String interpolation provides a more readable and convenient syntax to create formatted strings than a string composite formatting feature.
// Composite formatting:
Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
// String interpolation:
Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
Both calls produce the same output that is similar to:
Hello, Mark! Today is Wednesday, it's 19:40 now.

Or in Java you can use the printf variant of System.out:
System.out.printf("%s %s", foo, bar);
Remember to put in a "\n" [line feed] at the end, if there are multiple lines to print.

Related

How to add suffix at each line of large string

I have written a code to add Suffix at end of each line of a multi-line String but code only appends at the end of string. I am beginner. Can somebody help me in clarifying where I am mistaken? Here is my code:
protected void Prefix_Suffix_Btn_Click(object sender, EventArgs e)
{
String txt_input = Input_id.InnerText.ToString().Trim();
String txt_suffix = Suffix_id.InnerText.ToString().Trim();
String txt_output = Output_id.InnerText.ToString().Trim();
txt_input = txt_input.Replace(txt_suffix + "\n", "\n");
txt_input = txt_input + txt_suffix;
Output_id.InnerText = txt_input;
}
Input:
Line1
Line2
Line3
Desired output:
Line1AppededText
Line2AppendedText
Line3AppendedText
Let's Split text to lines, append each line and, finally, Join into string back:
string source = string.Join(Environment.NewLine,
"Line1",
"Line2",
"Line3");
// Let's have a look at the initial string;
Console.WriteLine(source);
Console.WriteLine();
string result = string.Join(Environment.NewLine, source
.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)
.Select(line => line + "AppendedText"));
Console.Write(result);
Outcome:
Line1
Line2
Line3
Line1AppendedText
Line2AppendedText
Line3AppendedText
The string of that comes out of your Input_id.InnerText is a string that consists of many lines. So if you want to append to each line, you need think of a way to treat those lines separately.
A line-end is denoted as the character '\n'. It looks like 2 characters to you, but the engine will treat it as one: line-end.
What you can do is split (break up) this string into multiple strings by snapping the string whenever you find a '\n'. You can do this by the following:
var lines = Input_id.InnerText.ToString().Split('\n');
Now lines contains an array of strings, each item in there containing a line of the input.
Now you could create a new string that will be built up by your split array as follows:
var newString = "";
foreach(var line in lines) {
newString += line + "<appendText>\n"; //note how we add the \n again since those disappeared by splitting
}
Now newString will contain the new string with each line containing the appended text.
A way shorter answer would be to for instance use the replace function like this:
var newString = Input_id.InnerText.ToString().Replace("\n", "<AppendedText>\n");
There is many ways to do what you want.
You just made a mistake when passing your values into the Replace() method. The documentation for String.Replace() defines it like this:
public string Replace (string oldValue, string newValue);
The first argument ("oldValue") should be the thing you want to replace. The second argument ("newValue") should be the thing you want to change it to. You've just got them the wrong way round. You're asking it to replace the new text (suffix and newline) with the old text (just the newline), which clearly it can't do because the suffix text doesn't exist in the string yet - and it wouldn't be logical even if it worked.
Change
txt_input = txt_input.Replace(txt_suffix + "\n", "\n");
to
txt_input = txt_input.Replace("\n", txt_suffix + "\n");
and you should be fine. As other answers alluded to, there may be nicer ways of achieving the same output, but in terms of fixing your original code this is all you should need to do.
Here's a live demo (just using console output instead of HTML elements): https://dotnetfiddle.net/jnzgUy

Transforming a string into a escaped char

The goal is to have a string input (coming from the frontend), and this string should be transformed to act as a escaped char in the backend.
In the following example I want the user to write "\" + "t", and the backend should interpret it as "\t" (= tab char):
var inputStr = #"\t"; // The input is a string written by a user: "\t" (backslash char + t char == #"\t" != "\t")
var outputStr = SomeOperation(inputStr); // ???
Console.WriteLine("A" + outputStr + "B <= should be tab separated");
I have tried:
var outputStr = inputStr.Replace("\", "");
This isn't something that is built in. Ultimately, "\t" == (a string of length 1 containing a tab character) is implemented by the C# compiler, not the runtime. There isn't a pre-existing implementation of this in the runtime, in part because each language (VB.NET, C#, F#, etc) can have their own rules.
You would need to write your own implementation with your own definitions of escape characters. Fortunately, it is mostly an exercise in .Replace(...). There are some edge cases to think about - in particular for ordering - though; for example, if \\ becomes \ and \n becomes newline; does \\n become \n? or does it become \(newline)? done naively, it can end up as just (newline) - i.e. foo.Replace(#"\\",#"\").Replace(#"\n","\n")
You can do something like this:
void Main()
{
Debug.Assert(ReplaceChar("hello\tworld", #"\t") == "helloworld"); // passed
}
string ReplaceChar(string str, string userInput)
{
switch (userInput)
{
case #"\t":
return str.Replace("\t","");
}
return str;
}
I have finally found an easy way to do it:
Regex.Unescape(inputStr);
See the documentation of the Regex.Unescape function for more details.
Example:
var ouptutStr = Regex.Unescape("\\t");
// ✓ Result: outputStr == "\t"
var outputStr = Char.Parse("\t").ToString();
gives
A B <= should be tab separated
It isn't seen here but in console it looks properly.

C# split string.format string with regex

I want to be able to split a formatting string on the variables' position indicators. It will chop out the curly braces and the position indicating numbers in between them.
So, the string:
string format = "{0} field needs to be set to '{1}' when {2}, Fixit. NOW!";
Should resolve to 3 strings.
" field needs to be set to '"
"' when "
", Fixit. NOW!"
We use string like the above 'format' to build error messages. My goal is to add generic unit tests that can take in the format and verify that an error message was generated that matches the expected format. Since both the error generation code and the unit test reference the same formatting, the unit tests won't need to be updated when minor changes are made to the message.
In the above example, i'll be able to test for the expected results, via a call to a new method called SplitFormatString.
string fieldName = "UserName";
string expectedValue = "Bob";
string condition = "excellence is a must";
string errorMessage = TestFieldValueErrorCase( );
AssertStringContainsAllThese(errorMessage, SplitFormatString(format), fieldName, expectedValue,condition);
With validation
public static void AssertStringContainsAllThese(string msg, string[] formatChunks, params string[] thingsToFind)
{
foreach (var txt in formatChunks.Concat(thingsToFind))
{
Assert.IsTrue(msg.Contains(txt), "Could not find <<" + txt + ">> in msg >>> " + msg);
}
}
I'd rather use regex than an inelegant approach using substrings.
I think you will want Regex.Split
Splits an input string into an array of substrings at the positions defined by a regular expression pattern.
Regex.Split("{0} field needs to be set to '{1}' when {2}, Fixit. NOW!", #"{\d+}");
Should output:
["","field needs to be set to '","' when ",", Fixit. NOW!"]

Add to string if string non empty

Sometime I want to join two strings with a space in between. But if second string is null, I don't want the space.
Consider following code:
void AssertFoo(bool cond, string message = null) {
...
Assert.Fail("Something is foo.{0}", message != null ? " " + message : "");
...
}
Is there a more elegant way to do that?
Here is one option that I like. It's better if you already have an IEnumerable<string> with your data, but it's easy enough even if you don't. It also clearly scales well to n strings being joined, not just 1 or two.
string[] myStrings = new string[]{"Hello", "World", null};
string result = string.Join(" ", myStrings.Where(str => !string.IsNullOrEmpty(str)));
Here is another option. It's a bit shorter for this one case, but it's uglier, harder to read, and not as extensible, so I would probably avoid it personally:
//note space added before {0}
Assert.Fail("Something is foo. {0}", message ?? "\b");
In this case we add the space to the format string itself, but if message is null we instead use the backspace character to remove the space that we know is before it in the message.
For newer versions of C# you can use the following extension method:
public static string Prepend(this string value, string prepend) => prepend + value;
It can be used like this:
Assert.Fail("Something is foo.{0}", message?.Prepend(" "));
Added in 2020:
Today I use this:
public static string Surround(this object value, string prepend, string append = null) => prepend + value + append;
Try this:
string joinedString = string.IsNullOrEmpty(message2) ? message1 : message1 + " " + message2;
Assert.Fail("Something is foo.{0}", (" " + message).TrimEnd());
Sure, this will result in a few string object creations, but it's unlikely such micro-optimization issues would matter in the vast majority of programs. It might be considered an advantage of this method that it handles not just null message, but a message of all whitespace as well.
Assert.Fail("Something is foo.{0}", message?.PadLeft(message.Lenght + 1, ' '));
Since C#6 you can use string interpolation like this:
$"Something is foo. {mssg}".TrimEnd();
See it in .NET Fiddle
The most elegant way is to use the inbuilt keyword of String class.
String.IsNullOrEmpty
This way you wont have a problem.

How to insert newline in string literal?

In .NET I can provide both \r or \n string literals, but there is a way to insert
something like "new line" special character like Environment.NewLine static property?
Well, simple options are:
string.Format:
string x = string.Format("first line{0}second line", Environment.NewLine);
String concatenation:
string x = "first line" + Environment.NewLine + "second line";
String interpolation (in C#6 and above):
string x = $"first line{Environment.NewLine}second line";
You could also use \n everywhere, and replace:
string x = "first line\nsecond line\nthird line".Replace("\n",
Environment.NewLine);
Note that you can't make this a string constant, because the value of Environment.NewLine will only be available at execution time.
If you want a const string that contains Environment.NewLine in it you can do something like this:
const string stringWithNewLine =
#"first line
second line
third line";
EDIT
Since this is in a const string it is done in compile time therefore it is the compiler's interpretation of a newline. I can't seem to find a reference explaining this behavior but, I can prove it works as intended. I compiled this code on both Windows and Ubuntu (with Mono) then disassembled and these are the results:
As you can see, in Windows newlines are interpreted as \r\n and on Ubuntu as \n
var sb = new StringBuilder();
sb.Append(first);
sb.AppendLine(); // which is equal to Append(Environment.NewLine);
sb.Append(second);
return sb.ToString();
One more way of convenient placement of Environment.NewLine in format string.
The idea is to create string extension method that formats string as usual but also replaces {nl} in text with Environment.NewLine
Usage
" X={0} {nl} Y={1}{nl} X+Y={2}".FormatIt(1, 2, 1+2);
gives:
X=1
Y=2
X+Y=3
Code
///<summary>
/// Use "string".FormatIt(...) instead of string.Format("string, ...)
/// Use {nl} in text to insert Environment.NewLine
///</summary>
///<exception cref="ArgumentNullException">If format is null</exception>
[StringFormatMethod("format")]
public static string FormatIt(this string format, params object[] args)
{
if (format == null) throw new ArgumentNullException("format");
return string.Format(format.Replace("{nl}", Environment.NewLine), args);
}
Note
If you want ReSharper to highlight your parameters, add attribute to the method above
[StringFormatMethod("format")]
This implementation is obviously less efficient than just String.Format
Maybe one, who interested in this question would be interested in the next question too:
Named string formatting in C#
string myText =
#"<div class=""firstLine""></div>
<div class=""secondLine""></div>
<div class=""thirdLine""></div>";
that's not it:
string myText =
#"<div class=\"firstLine\"></div>
<div class=\"secondLine\"></div>
<div class=\"thirdLine\"></div>";
If you really want the New Line string as a constant, then you can do this:
public readonly string myVar = Environment.NewLine;
The user of the readonly keyword in C# means that this variable can only be assigned to once. You can find the documentation on it here. It allows the declaration of a constant variable whose value isn't known until execution time.
static class MyClass
{
public const string NewLine="\n";
}
string x = "first line" + MyClass.NewLine + "second line"
newer .net versions allow you to use $ in front of the literal which allows you to use variables inside like follows:
var x = $"Line 1{Environment.NewLine}Line 2{Environment.NewLine}Line 3";
If you are working with Web application you can try this.
StringBuilder sb = new StringBuilder();
sb.AppendLine("Some text with line one");
sb.AppendLine("Some mpre text with line two");
MyLabel.Text = sb.ToString().Replace(Environment.NewLine, "<br />")
If I understand the question: Couple "\r\n" to get that new line below in a textbox. My example worked -
string s1 = comboBox1.Text; // s1 is the variable assigned to box 1, etc.
string s2 = comboBox2.Text;
string both = s1 + "\r\n" + s2;
textBox1.Text = both;
A typical answer could be s1
s2 in the text box using defined type style.
I like more the "pythonic way"
List<string> lines = new List<string> {
"line1",
"line2",
String.Format("{0} - {1} | {2}",
someVar,
othervar,
thirdVar
)
};
if(foo)
lines.Add("line3");
return String.Join(Environment.NewLine, lines);
Here, Environment.NewLine doesn't worked.
I put a "<br/>" in a string and worked.
Ex:
ltrYourLiteral.Text = "First line.<br/>Second Line.";

Categories