WriteLine over multiple lines with multiple values - c#

trying to understand!!
string myValue1 = "1";
string myValue2 = "2";
Console.WriteLine(myValue1, myValue2);
This only prints out the first value, if one use + the it concatenates them together. is there a way to have the two values printed on separate lines.
I can use two WriteLines (one for each Value) but I am trying to be more efficient (or Stupid)!!

Use Environment.NewLine for printing values on different lines. Use Console.WriteLine Method (String, Object[]) overload which takes a string format and values.
Console.WriteLine("{0}{1}{2}", myValue1, Environment.NewLine, myValue2);
If this is a single statement, than I really doubt if it will give you any performance gain.

You are using the format overload http://msdn.microsoft.com/en-us/library/828t9b9h(v=vs.110).aspx
This one supports placeholders {0}, {1}... The first argument is the format and the subsequent arguments are put in the placeholder. Because your string does not have any placeholders the second value is missing. For what you want to do you'd best just call WriteLine twice.
Console.WriteLine(myValue1);
Console.WriteLine(myValue2);
Concatenating new line will make your code harder to read. Don't try to be efficient this way. It is stupid :)

You can also use a verbatim string literal # and it will look like that:
Console.WriteLine(#"{0}
{1}", myValue1, myValue2);
The output will be on separate lines. However, in my opinion the c# doesn't look well written.

concat an Environment.NewLine //

If by efficient you mean write less code you can do this:
static void Main(string[] args)
{
WriteMultiLine(1,2, "hello", TimeSpan.FromMinutes(3));
Console.ReadLine();
}
public static void WriteMultiLine(params object[] values)
{
foreach (var value in values)
{
Console.WriteLine(value);
}
}
You can print whatever you want on different lines.
The output is:
1
2
hello
00:03:00

Related

Trouble Converting string [] to int []

using System;
using System.IO;
namespace Test_Arrays_and_Files
{
class Program
{
static void Main(string[] args)
{
string tFile = #"C:\Programming\GLO\DC\dcw.txt";
string read = File.ReadAllText(tFile);
string[] test = read.Split(',');
int[] ints = Array.ConvertAll(test, int.Parse);
Console.WriteLine(ints[0]);
}
}
}
Input Data:
Text File Contents:(1 value per line,)
35,
35,
40,
40,
40,
getting System.FormatException: Input string was not in correct format
please help and sorry for bad post I'm new here
There are two issues in your code,
Your string is ending with , which is creating empty record after the split. This is the reason you are getting the error.
Your delimiter could be $",{Environment.NewLine}" not only ','.
So to convert given string to int array, first Trim() the input string by , and then split by $",{Environment.NewLine}".
Like,
using System.Linq;
...
var result = str.Trim(',') //Remove leading and trailing comma(s), You can use `TrimEnd()` as well
.Split($",{Environment.NewLine}", StringSplitOptions.RemoveEmptyEntries) //Split by given delimiter.
.Select(int.Parse)
.ToArray(); //Convert string[] to int[]
Try online
You're only getting it because the file has a comma at the end, which means Split ends up churning out an empty string in the very last position. int.Parse will choke on the empty string
Plenty of ways you could solve it, one is to tell Split not to return you empties, by changing the split line of your code to:
string[] test = read.Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries);
You could instead trim the comma off the end, but using the above approach would mean your parsing would survive a blank line in the middle of the file too so overall it's more robust
Generally when parsing strings it's more robust to use TryParse than Parse. TryParse takes in the number variable to set the result to and returns you a Boolean telling if the parsing succeeded
int[] ints = Array.ConvertAll(test, GetIntOrMinusOne);
//put a method helper
private int GetIntOrMinusOne(string s){
if(int.TryParse(s, out var t)
return t;
return -1;
}
For this we need to get a bit more involved with the ConvertAll call. Instead of telling ConvertAll to call a "method that converts a string to an int" like int.Parse, we need to write our own mini method that tries to parse and if it fails return something like -1, then nominate that as the method to call to do the conversion, not int.Parse
It's important to note that this would introduce -1 into the resulting int[] array wherever there was bad data in the string array.. In your later processing you would then do some check to avoid them (such as skipping them)
You can shorten that code above by turning the method into a lambda:
int[] ints = Array.ConvertAll(test, s => int.TryParse(s, out var t) ? t : -1);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
a lambda; "just the important parts of a method"
But I'm not sure that you'll have come across lambdas yet, judging by the style of the rest of the code

Is it possible to store a regex match and use part of it as a list enumerator?

I have created a MadLibs style game where the user enters responses to prompts which in turn replace blanks, represented by %s0, %s1 etc., in a story. I have this working using a for loop but someone else suggested I could do it using regex. What I have so far is below, which replaces all instances of %s+number with "wibble". What I was wondering is if it is possible to store the number found by the regex in a temporary variable and in turn use that to return a value from the list Words? E.g. return Regex.Replace(story, pattern, Global.Words[x]); where x is the number returned by the regex pattern as it goes over the string.
static void Main(string[] args)
{
Globals.Words = new List<string>();
Globals.Words.Add("nathan");
Globals.Words.Add("bob");
var text = "Once upon a time there was a %s0 and it was %s1";
Console.WriteLine(FindEscapeCharacters(text));
}
public static string FindEscapeCharacters(string story)
{
var pattern = #"%s([0-9]+)";
return Regex.Replace(story, "%s([0-9]+)", "wibble");
}
Thanks in advance, Nathan.
Not a direct answer to your question about regexes, but if I understand you correctly, there is an easier way to do this:
string baseString = "I have a {0} {1} in my {0} {2}.";
List<string> words = new List<string>() { "red", "cat", "hat" };
string outputString = String.Format(baseString, words.ToArray());
outputString will be I have a red cat in my red hat..
Is that not what you want, or is there more to your question that I'm missing?
Minor elaboration
String.Format uses the following signature:
string Format(string format, params object[] values)
The neat thing about params is that you can either list values separately:
var a = String.Format("...", valueA, valueB, valueC);
but you can also pass in an array directly:
var a = String.Format("...", valueArray);
Note that you can't mix and match the two approaches.
Yes, you are very close in your attempt with Regex.Replace; the last step is to change constant "wibble" into lambda match => how_to_replace_the_match:
var text = "Once upon a time there was a %s0 and it was %s1";
// Once upon a time there was a nathan and it was bob
var result = Regex.Replace(
text,
"%s([0-9]+)",
match => Globals.Words[int.Parse(match.Groups[1].Value)]);
Edit: In case you don't want working with capturing groups by their numbers, you can name them explicitly:
// Once upon a time there was a nathan and it was bob
var result = Regex.Replace(
text,
"%s(?<number>[0-9]+)",
match => Globals.Words[int.Parse(match.Groups["number"].Value)]);
There is an overload of Regex.Replace that, rather than taking a string for the last argument, takes a MatchEvaluator delegate - a function that takes a Match object and returns a string.
You could make that function parse the integer from the Match's Groups[1].Value property and then use that to index into your list, returning the string you find.

Split string with plus sign as a delimiter

I have an issue with a string containing the plus sign (+).
I want to split that string (or if there is some other way to solve my problem)
string ColumnPlusLevel = "+-J10+-J10+-J10+-J10+-J10";
string strpluslevel = "";
strpluslevel = ColumnPlusLevel;
string[] strpluslevel_lines = Regex.Split(strpluslevel, "+");
foreach (string line in strpluslevel_lines)
{
MessageBox.Show(line);
strpluslevel_summa = strpluslevel_summa + line;
}
MessageBox.Show(strpluslevel_summa, "summa sumarum");
The MessageBox is for my testing purpose.
Now... The ColumnPlusLevel string can have very varied entry but it is always a repeated pattern starting with the plus sign.
i.e. "+MJ+MJ+MJ" or "+PPL14.1+PPL14.1+PPL14.1" as examples.
(It comes form Another software and I cant edit the output from that software)
How can I find out what that pattern is that is being repeated?
That in this exampels is the +-J10 or +MJ or +PPL14.1
In my case above I have tested it by using only a MessageBox to show the result but I want the repeated pattering stored in a string later on.
Maybe im doing it wrong by using Split, maybe there is another solution.
Maybe I use Split in the wrong way.
Hope you understand my problem and the result I want.
Thanks for any advice.
/Tomas
How can I find out what that pattern is that is being repeated?
Maybe i didn't understand the requirement fully, but isn't it easy as:
string[] tokens = ColumnPlusLevel.Split(new[]{'+'}, StringSplitOptions.RemoveEmptyEntries);
string first = tokens[0];
bool repeatingPattern = tokens.Skip(1).All(s => s == first);
If repeatingPattern is true you know that the pattern itself is first.
Can you maybe explain how the logic works
The line which contains tokens.Skip(1) is a LINQ query, so you need to add using System.Linq at the top of your code file. Since tokens is a string[] which implements IEnumerable<string> you can use any LINQ (extension-)method. Enumerable.Skip(1) will skip the first because i have already stored that in a variable and i want to know if all others are same. Therefore i use All which returns false as soon as one item doesn't match the condition(so one string is different to the first). If all are same you know that there is a repeating pattern which is already stored in the variable first.
You should use String.Split function :
string pattern = ColumnPlusLevel.Split("+")[0];
...but it is always a repeated pattern starting with the plus sign.
Why do you even need String.Split() here if the pattern always only repeats itself?
string input = #"+MJ+MJ+MJ";
int indexOfSecondPlus = input.IndexOf('+', 1);
string pattern = input.Remove(indexOfSecondPlus, input.Length - indexOfSecondPlus);
//pattern is now "+MJ"
No need of string split, no need to use LinQ
String has a method called Split which let's you split/divide the string based on a given character/character-set:
string givenString = "+-J10+-J10+-J10+-J10+-J10"'
string SplittedString = givenString.Split("+")[0] ///Here + is the character based on which the string would be splitted and 0 is the index number
string result = SplittedString.Replace("-","") //The mothod REPLACE replaces the given string with a targeted string,i added this so that you can get the numbers only from the string

Parse words out of a string

I need to parse a string from NHRM__Location__c to just Location. I feel really dumb because this is not my first rodeo. I do not want to add the code in an array. NHRM is a namespace that may change depending on who's using it so at some point that will be a key in the app.config file.
I was thinking of just splitting the string on __ and then loading the rest of the word into a character array and trimming that guy down but I feel like I may be waaaay over complicating things.
I have put this into a .Net Fiddle for you using this code:
using System;
public class Program
{
public static void Main()
{
string stringToSplit = "NHRM__Location__c"; // 2 underscores in each location
char[] sep = new char[] {'_', '_'};
string newString = stringToSplit.Split(sep)[2];
Console.WriteLine(newString);
}
}
I know this is similar to the 1st answer, but I just wanted to prove that [2] does work, well at least for me in .Net Fiddle.
I hope this helps!
Update
System.String
Return Value - An array whose elements contain the substrings from this instance that are delimited by one or more characters in separator
So if I were to change the code to [4] then it would return just c.. and [0] would return NHRM.. the array values do not include the separator
Use this:
string sample = "NHRM__Location__c";
Console.WriteLine(sample.Split('_')[2]);

string.insert multiple values. Is this possible?

Im still learning in C#, and there is one thing i cant really seem to find the answer to.
If i have a string that looks like this "abcdefg012345", and i want to make it look like "ab-cde-fg-012345"
i tought of something like this:
string S1 = "abcdefg012345";
string S2 = S1.Insert(2, "-");
string S3 = S2.Insert(6, "-");
string S4 = S3.Insert.....
...
..
Now i was looking if it would be possible to get this al into 1 line somehow, without having to make all those strings.
I assume this would be possible somehow ?
Whether or not you can make this a one-liner (you can), it will always cause multiple strings to be created, due to the immutability of the String in .NET
If you want to do this somewhat efficiently, without creating multiple strings, you could use a StringBuilder. An extension method could also be useful to make it easier to use.
public static class StringExtensions
{
public static string MultiInsert(this string str, string insertChar, params int[] positions)
{
StringBuilder sb = new StringBuilder(str.Length + (positions.Length*insertChar.Length));
var posLookup = new HashSet<int>(positions);
for(int i=0;i<str.Length;i++)
{
sb.Append(str[i]);
if(posLookup.Contains(i))
sb.Append(insertChar);
}
return sb.ToString();
}
}
Note that this example initialises StringBuilder to the correct length up-front, therefore avoiding the need to grow the StringBuilder.
Usage: "abcdefg012345".MultiInsert("-",2,5); // yields "abc-def-g012345"
Live example: http://rextester.com/EZPQ89741
string S1 = "abcdefg012345".Insert(2, "-").Insert(6, "-")..... ;
If the positions for the inserted strings are constant you could consider using string.Format() method. For example:
string strTarget = String.Format("abc{0}def{0}g012345","-");
string s = "abcdefg012345";
foreach (var index in [2, 6, ...]
{
s = s.Insert(index, "-");
}
I like this
StringBuilder sb = new StringBuilder("abcdefg012345");
sb.Insert(6, '-').Insert(2, '-').ToString();
String s1 = "abcdefg012345";
String seperator = "-";
s1 = s1.Insert(2, seperator).Insert(6, seperator).Insert(9, seperator);
Chaining them like that keeps your line count down. This works because the Insert method returns the string value of s1 with the parameters supplied, then the Insert function is being called on that returned string and so on.
Also it's worth noting that String is a special immutable class so each time you set a value to it, it is being recreated. Also worth noting that String is a special type that allows you to set it to a new instance with calling the constructor on it, the first line above will be under the hood calling the constructor with the text in the speech marks.
Just for the sake of completion and to show the use of the lesser known Aggregate function, here's another one-liner:
string result = new[] { 2, 5, 8, 15 }.Aggregate("abcdefg012345", (s, i) => s.Insert(i, "-"));
result is ab-cd-ef-g01234-5. I wouldn't recommend this variant, though. It's way too hard to grasp on first sight.
Edit: this solution is not valid, anyway, as the "-" will be inserted at the index of the already modified string, not at the positions wrt to the original string. But then again, most of the answers here suffer from the same problem.
You should use a StringBuilder in this case as Strings objects are immutable and your code would essentially create a completely new string for each one of those operations.
http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
Some more information available here:
http://www.dotnetperls.com/stringbuilder
Example:
namespace ConsoleApplication10
{
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder("abcdefg012345");
sb.Insert(2, '-');
sb.Insert(6, '-');
Console.WriteLine(sb);
Console.Read();
}
}
}
If you really want it on a single line you could simply do something like this:
StringBuilder sb = new StringBuilder("abcdefg012345").Insert(2, '-').Insert(6, '-');

Categories