String IndexOf and Substring C# - c#

I'm working on to read a textfile which contains this line of string. And to fetch its value to my integer variables.. I want to try to avoid using Class or Arrays.
string cont = "[]val1:1val2:0val3:1";
int split = cont.IndexOf("val3:");
int val3 = Int32.Parse(cont.Substring(split + 5)); // this line successfully convert string to int
cont.Remove(split);
Console.WriteLine("Value3: " + val3 + " Content: " + cont);
split = cont.IndexOf("val2:");
int val2 = Int32.Parse(cont.Substring(split + 5)); // LINE 21
cont.Remove(split);
Console.WriteLine("Value2: " + val2 + " Content: " + cont);
split = cont.IndexOf("val1:");
int SilverCoins = Int32.Parse(cont.Substring(split + 5));
cont.Remove(split);
Console.WriteLine("Value1: " + val1 + " Content: " + cont);
When I run this code, I get an Unhandled Exception which states Input string was not in a correct format, at System.Int32.Parse(String s), line 21. :(
So, my desired output should be
Value3: 1 Content: []val1:1val2:0
Value2: 0 Content: []val1:1
Value1: 1 Content: []

Your problem is in this code cont.Remove(split);
Strings are immutable, so you need to reassign new value.
In order to fix it you need to write
cont = cont.Remove(split);

You aren't putting the remove result back into the string, try doing this:
cont = cont.Remove(split);

When we perform some action on string it does not make changes in the same string instance. Instead it returns a new string instance. This concept is known as Immutability.
When you do
cont.Remove(split);
it does not update cont. Instead it returns updated string which you need to capture like this
cont = cont.Remove(split);

Restoring the cont value after calling the Remove method is missing.
Modified Code:
string cont = "[]val1:1val2:0val3:1";
int split = cont.IndexOf("val3:");
int val3 = Int32.Parse(cont.Substring(split + 5)); // this line successfully convert string to int
cont = cont.Remove(split);
Console.WriteLine("Value3: " + val3 + " Content: " + cont);
split = cont.IndexOf("val2:");
int val2 = Int32.Parse(cont.Substring(split + 5)); // but this line fails to convert from string to int..
cont = cont.Remove(split);
Console.WriteLine("Value2: " + val2 + " Content: " + cont);
split = cont.IndexOf("val1:");
int val1 = Int32.Parse(cont.Substring(split + 5));
cont = cont.Remove(split);
Console.WriteLine("Value1: " + val1 + " Content: " + cont);

Two ways you can fix the problem.
C# strings are immutable, so you have to modify your code to
cont = cont.Remove(split);
Another approach(might be best for your case), when using the SubString specify length, so you get specified number of characters.
split = cont.IndexOf("val2:");
int val2 = Int32.Parse(cont.Substring(split + 5, 1));

0val3:1 is not a valid number, therefore int.Parse fails. If you need to extract the 0 from the beginning of this string, you can refer to Parse an integer from a string with trailing garbage .
Also, the result of cont.Remove(split); is never used in your code snippet, and thus does nothing but waste CPU cycles. Considering you notice this behavior in the Console.WriteLine, and simply complain about an exception, I can only assume this was intentional?
Note that it looks like you're trying to extract key-value pairs from a string. A regular expression similar to val([^:]+):([0-9]+) might be a better tool here.
Alternatively, you can split on val and take the left/right of the colon. Something like:
var vals = cont.Split(new[] {"val"}, StringSplitOptions.None)
.Skip(1) //ignore any garbage at the beginning
.Select(x => x.Split(':'))
.ToDictionary(x => x[0], x => int.Parse(x[1]));

Related

What does "str" + x + "str" mean?

Why would you use "str" + x + "str" in ImageLocation.
private void CreateEnemies()
{
Random rnd = new Random();
int x = rnd.Next(1, kindOfEnemies + 1);
PictureBox enemy = new PictureBox();
int loc = rnd.Next(0, panel1.Height - enemy.Height);
enemy.SizeMode = PictureBoxSizeMode.StretchImage;
enemy.ImageLocation = "Aliens/" + x + ".png";
}
I don't understand why you would use this.
The + operator is used for adding. If used on a string it will not add two strings, but concatenate them:
var text = "Hello" + "World" + "String";
Console.WriteLine(text); // Prints "HelloWorldString"
So the code above just constructs a string. Because the variable x is not of type int, .Net will automatically call .ToString().
int x = 5;
var text1 = "Aliens/" + x +".png"; // is the same as below.
var text2 = "Aliens/" + x.ToString() +".png"; // is the same as above.
Console.WriteLine(text); // Prints "Aliens/5.png"
In C# version 6 and above you can also use string interpolation, which makes things clearer:
var text1 = $"Aliens/{x}.png"; // is the same as below.
var text2 = $"Aliens/{x.ToString()}.png"; // is the same as above.
With string interpolation, you can embed variables into a string, by placing them into curly braces.
Note that the string has to start with a $.
+ is used for string concatenation
This is a way to randomize the image of the alien that you get.
Your solution has a folder called Aliens with files named 0.png, 1.png, 2.png, and so on in it. Each file has an image of an "alien", which your program loads into a PictureBox. Your code picks one of these files at random, using string concatenation.
With C# 6 and newer you can use string interpolation:
enemy.ImageLocation = $"Aliens/{x}.png";
It is concatenating strings together. So "Aliens/" + The string value of 'x' + ".png" are being 'added' together.
Lets say:
int x = 1
The output string would be
"Aliens/1.png"

Split and combine two different strings

I am trying to create a string and below is the thing which i am trying to achieve:
String first = "Previous.value1 | Previous.value2";
String second = "New.value1| New.value2";
I am trying to create final string like this:
string final ="generate Previous.value1 cross New.value1 ? Previous.value1 cross New.value2";
But problem is when i will have mismatch like below:
String first = "Previous.value1 | Previous.value2";
String second = "New.value1";
Then i want to have like this because i dont have matching value for Previous.Value2 in second variable:
string final ="generate Previous.value1 cross New.value1";
So far i am successfully in generating final string when i have same count of value in both the string.
string final = "generate";
if (first.Split('|').Count() - second.Split('|').Count() == 0)
{
int i = 0;
foreach (var item in first.Split('|').Count())
{
if (i == 0)
final = final + item + " cross " + second.Split('|')[i];
else
final = final + " ? " + item + " cross " + second.Split('|')[index];
i++;
}
}
Try this LINQ query (using the Zip extension method):
var zippedQry = first.Split('|').Zip(second.Split('|'),
(f, s) => f.Trim() + " cross " + s.Trim());
string final = "generate " + String.Join(" ? ", zippedQry.ToArray());
To remain in the style that you use, I would suggest to first split both strings
String first = "Previous.value1 | Previous.value2";
String second = "New.value1 | New.value2";
string final = "generate ";
string[] first_values = first.Split('|');
string[] second_values = second.Split('|');
Then you can just orient yourself on the shortest array. If you have in the second_values not enough corresponding values for the first_values you collect only the corresponding ones. Using a normal for-loop:
// run until the length of the shortest one
for (int i = 0; i < Math.Min(first_values.Length, second_values.Length); i++)
{
// bild the normal cross-version for the first position
string sentence = first_values[i] + " cross " + second_values[i];
// if on first position use normal version otherwise put a ? infront of it
final += i == 0 ? sentence : " ? " + sentence;
}
This loop should handle also string like this:
String first = "Previous.value1 | Previous.value2 | Previous.value3 | Previous.value4";
String second = "New.value1 | New.value2 | New.value3";

Bind strings with quotation

I am sending some code to R.net wrapper as strings. If there are no any quation marks inside , it's simple with #
engine.Evaluate(#"remove_outliersabove <- function(x, na.rm = TRUE, ...) {
qnt <- quantile(x, probs=c(.25, .75), na.rm = na.rm, ...);
H <- 1.5 * IQR(x, na.rm = na.rm);
y <- x;
y[x > (qnt[2] + H)] <- NA;
y;
}");
but if I have "" inside then things get complicated and I need to cut and join strings like this
engine.Evaluate("for (k in 1:length(dates))" +
"{ " +
"tmp <- grep(dates[[k]],as.Date(data$timestamp, format=\"%d/%m/%Y\"))" +
"if (length(tmp)!=96)" +
"{ " +
"to_remove[[it]]=k it=it+1" +
"}" +
"}");
is there better option ? for example to use # and then mark quation mark somehow ?
When you use #"...", you can escape the " character by doubling it to "". So
string str = "hello ""world""!";
is
hello "world"!
How about string.Format("{0} bla bla {1}",string1,string2)? does it make it look neater?

Changing position of words in a string

I have a string let say,
string temp1 = "25 10 2012"
but I want this,
"2012 10 25"
what would be the best way of doing it. format will always be like this.
Looks like its a date. You can parse the string to DateTime, using DateTime.ParseExact and then use .ToString to return formatted result.
DateTime dt = DateTime.ParseExact(temp1, "dd MM yyyy", CultureInfo.InvariantCulture);
Console.Write(dt.ToString("yyyy MM dd"));
You may use that DateTime object later in your code, and also apply different formatting (if you need)
try this split string and reverse array , and this will work for string of any length ...
string[] myArray = temp1.Split(' ');
Array.Reverse( myArray );
string reverse =string.Join(" ", myArray );
You could do it using the Split command and then recombining the sub strings:
String[] subStrs = temp1.Split( ' ' );
String final = subStrs[2] + " " + subStrs[1] + " " + subStrs[0];
So you want to split words and change the order, you can use LINQ:
var words = temp1.Split(' ');
String newWord = string.Join(" ", words.Reverse());
or if you don't want to swap all words but only swap the first and last word:
String first = words.Last();
String last = words.First();
String newWord = first + " "
+ string.Join(" ", words.Skip(1).Take(words.Length - 2))
+ " " + last;
You could either use a RegEx or split the string and rejoin it in reverse order.
string s = "2012 10 25";
string[] tokens = s.Split(' ');
Array.Reverse(tokens);
string final = string.Join(" ", tokens);
If Your string has always 10 character (with spaces), You can do the following:
string str = "26 10 2012"
str = str.Substring(6, 4) + " " + str.Substring(3, 2) + " " + str.Substring(0, 2)
you can use string.split(" ").reverse().join(" ").
You can use split, this function will split your string to array on white space as condition then reverse the array and re join based on white space
let string="25 10 2012";
let output=string.split(" ").reverse().join(" ");
console.log(output)

save values of array in one string

i have an array with 4 values:
string[] selectedObject;
how can i save all 4 values of array in string like:
string selectedObjects = "";
i need one string like this:
selectedObjects = "123; 132; 231; 132;";
string selectedObjects = string.Join("; ", selectedObject);
This will produce the output "123; 132; 231; 132" - If you really wanted another ; at the end you could add this manually to have all bases covered:
if (!string.IsNullOrEmpty(selectedObjects))
selectedObjects = selectedObjects + ";";
This will produce the right output for any selectedObject array length, including zero.
String selectedObjects = selectedObject.Aggregate((aggregation, currentString) => aggregation + "; " + currentString);

Categories

Resources