Break string at an index - c#

I am trying to break a string at position 4 and then save as another string. The substring works with simple A-Z letters but can you help me with this.
string messageToSend = "P0011%$1%$6%$1%$1%$Heat And Smoke Detector|1%$1%$7%$1%$1%$Sounder|1%$1%$9%$2%$1%$Input Device Zone 2|";
string myString = messageToSend.Substring(1, messageToSend.Length);

Substring has two signatures:
The one you are currently using is Substring(int startIndex, int length).
Your code example at the top starts at index 1 (the second character), and goes "length of string" characters. The problem is this would go one character past the end of the string.
The easy fix for this situation is
string myString = messageToSend.Substring(1, messageToSend.Length - 1);
Note the -1. This will be the same as the "offset" value you are applying to the start of the string.
However, there is a much easier way to do this, and that's with the second form of the method: Substring(int startIndex).
This only asks for the index to start at, and goes all the way to the end of the string. You don't have to worry how long the string it; it will take care of that for you.
Your example can be filtered down to this:
string myString = messageToSend.Substring(1);
Or, if you wanted to start at the 4th index:
string myString = messageToSend.Substring(4);

There's a length mismatch for the remainder of the string. If you need the entire string after your specific index, just use this overload of Substring:
string messageToSend = "P0011%$1%$6%$1%$1%$Heat And Smoke Detector|1%$1%$7%$1%$1%$Sounder|1%$1%$9%$2%$1%$Input Device Zone 2|";
string myString = messageToSend.Substring(4);
If specifying the length, you'd need to account for the characters you removed from the string.
Index of 4 means 5 characters (indexes 0, 1, 2, 3, and 4)
Length starts counting at one, not zero, so add one more to the number of characters to remove.
Total chars removed during your substring operation: 6
If specifying the length of the string to remove, the code would be:
string messageToSend = "P0011%$1%$6%$1%$1%$Heat And Smoke Detector|1%$1%$7%$1%$1%$Sounder|1%$1%$9%$2%$1%$Input Device Zone 2|";
string myString = messageToSend.Substring(1, messageToSend.Length - 6);

Set string.Length - 1
string messageToSend = "P0011%$1%$6%$1%$1%$Heat And Smoke Detector|1%$1%$7%$1%$1%$Sounder|1%$1%$9%$2%$1%$Input Device Zone 2|";
string myString = messageToSend.Substring(1, messageToSend.Length - 1);

Related

How to replace multiple characters in a string with other multiple characters (another string) without replacing other ocurrences?

I'm making a console application for IP assignment where a user simply enters the number of networks, the number of hosts per network and the initial network IP address, and this generates the full IP assignment table.
My biggest issue right now is that say I have a string with "172.16.0.0".
I want to grab the 0 at the end, convert it to an int, add a certain number of hosts (say, 0 + 512), and if it goes over 255, I want it to instead grab the previous 0 and replace it with a 1 instead then test it again. But I'm mostly having issues with replacing the numbers in the initial string. Since strings aren't mutable, I obviously have to make a new string with the change, but I can't see how to do this.
I've so far tried finding the index where the change will be made using the string.split function and indexof and making that an int variable called datIndex. Then I change the "172.16.0.0" string to a character array, then tried swapping the character in the previously defined index, however this limits me to a single character, which wouldn't work for a number with more than one digit. Also tried using stringbuilder but the stringbuilder object seems to be a char type so I end up in the same place, can't equal the value in the index I want to change to the new number.
string test = "172.16.0.0";
int datIndex = test.IndexOf(test.Split('.')[2]);
char[] c = test.ToCharArray();
c[datIndex] = '201'; //Not possible because more than one digit
//Also tried the following
datIndex = test.IndexOf(test.Split('.')[2]);
StringBuilder sb = new StringBuilder(test);
sb[datIndex] = '201'; //Cannot implicitly convert type string to char
string temp2 = sb.ToString();
test = temp2; //Changed string
In this example, I'd like to change the penultimate "0" in the "172.16.0.0" string to a "201" (this number would be obtained by a sum of two numbers so ideally they'd both first be integers).
However with both methods I've tried, I can't fit a number bigger than one digit into that index.
This is maybe what you are looking for:
string ip = "127.16.0.0";
string ipNumbers = ip.Split('.');
int a = int.Parse (ipNumbers[0]);
int b = int.Parse (ipNumbers[1]);
int c = int.Parse (ipNumbers[2]);
int d = int.Parse (ipNumbers[3]);
//now you have in a,b,c and d all the ip numbers, do the math with them and then do this:
ip = $"{a}.{b}.{c}.{d}";

How to split my String into 3 delimited Strings (regardless of SubString Length)?

I'm storing strings in an array. An example would be:
ssnDateTime = "123456789|20140225|114528"
I was attempting to store each substring into it's own variable for use, like the below:
string SSN = ssnDateTime.Substring(0, 9);
string Date = ssnDateTime.Substring(ssnDateTime.Length - 15, 8);
string Time = ssnDateTime.Substring(19);
This worked fine for 5 of my 10 test records, but the 6th has a time value of 91514, leading to my 3 strings being:
SSN = 123456789
Date = |2014022
Time = 91514
When my application attempts to run INSERT INTO Library.TrackingTable (SSN, DATE, TIME) VALUES ("123456789", "|2014021", "91514"), The AS400 naturally complains about the | in the Date value.
What is a way I can get each of the SSN, Date, and Time values out of my main string with the delimiters, regardless of the substring length (to prevent the mentioned issue when time is a shorter value than 6 characters)?
SSN will naturally be consistently 9 characters, and Date will be in the 8 character format of 20140225, but Time can be either the 5 or 6 characters depending on value.
Seems to be a perfect fit for string.Split
ssnDateTime = "123456789|20140225|114528"
string[] subs = ssnDateTime.Split('|');
string SSN = subs[0];
string Date = subs[1];
string Time = subs[2];
string.Split returns an array of strings splitting the orginal string at the separator passed as argument.
Of course this code doesn't check if the resulting string array contains really three elements, in a production environment a check like
if(subs.Length > 0
date = subs[1];
if(subs.Length > 1)
Time = subs[2];
should be mandatory....
string[] parts = "123456789|20140225|114528".Split('|');
http://www.dotnetperls.com/split

Most efficient way to parse a delimited string in C#

This has been asked a few different ways but I am debating on "my way" vs "your way" with another developer. Language is C#.
I want to parse a pipe delimited string where the first 2 characters of each chunk is my tag.
The rules. Not my rules but rules I have been given and must follow.
I can't change the format of the string.
This function will be called possibly many times so efficiency is key.
I need to keep is simple.
The input string and tag I am looking for may/will change during runtime.
Example input string: AOVALUE1|ABVALUE2|ACVALUE3|ADVALUE4
Example tag I may need value for: AB
I split string into an array based on delimiter and loop through the array each time the function is called. I then looked at the first 2 characters and return the value minus the first 2 characters.
The "other guys" way is to take the string and use a combination of IndexOf and SubString to find the starting point and ending point of the field I am looking for. Then using SubString again to pullout the value minus the first 2 characters. So he would say IndexOf("|AB") the find then next pipe in the string. This would be the start and end. Then SubString that out.
Now I should think that IndexOf and SubString would parse the string each time at a char by char level so this would be less efficient than using large chunks and reading the string minus the first 2 characters. Or is there another way the is better then what both of us has proposed?
The other guy's approach is going to be more efficient in time given that input string needs to be reevaluated each time. If the input string is long, it is also won't require the extra memory that splitting the string would.
If I'm trying to code a really tight loop I prefer to directly use array/string operators rather than LINQ to avoid that additional overhead:
string inputString = "AOVALUE1|ABVALUE2|ACVALUE3|ADVALUE4";
static string FindString(string tag)
{
int startIndex;
if (inputString.StartsWith(tag))
{
startIndex = tag.Length;
}
else
{
startIndex = inputString.IndexOf(string.Format("|{0}", tag));
if (startIndex == -1)
return string.Empty;
startIndex += tag.Length + 1;
}
int endIndex = inputString.IndexOf('|', startIndex);
if (endIndex == -1)
endIndex = inputString.Length;
return inputString.Substring(startIndex, endIndex - startIndex);
}
I've done a lot of parsing in C# and I would probably take the approach suggested by the "other guys" just because it would be a bit lighter on resources used and likely to be a little faster as well.
That said, as long as the data isn't too big, there's nothing wrong with the first approach and it will be much easier to program.
Something like this may work ok
string myString = "AOVALUE1|ABVALUE2|ACVALUE3|ADVALUE4";
string selector = "AB";
var results = myString.Split('|').Where(x => x.StartsWith(selector)).Select(x => x.Replace(selector, ""));
Returns: list of the matches, in this case just one "VALUE2"
If you are just looking for the first or only match this will work.
string result = myString.Split('|').Where(x => x.StartsWith(selector)).Select(x => x.Replace(selector, "")).FirstOrDefault();
SubString does not parse the string.
IndexOf does parse the string.
My preference would be the Split method, primarily code coding efficiency:
string[] inputArr = input.Split("|".ToCharArray()).Select(s => s.Substring(3)).ToArray();
is pretty concise. How many LoC does the substring/indexof method take?

Remove last characters from a string in C#. An elegant way?

I have a numeric string like this 2223,00. I would like to transform it to 2223. This is: without the information after the ",". Assume that there will be only two decimals after the ",".
I did:
str = str.Remove(str.Length - 3, 3);
Is there a more elegant solution? Maybe using another function? -I donĀ“t like putting explicit numbers-
You can actually just use the Remove overload that takes one parameter:
str = str.Remove(str.Length - 3);
However, if you're trying to avoid hard coding the length, you can use:
str = str.Remove(str.IndexOf(','));
Perhaps this:
str = str.Split(",").First();
This will return to you a string excluding everything after the comma
str = str.Substring(0, str.IndexOf(','));
Of course, this assumes your string actually has a comma with decimals. The above code will fail if it doesn't. You'd want to do more checks:
commaPos = str.IndexOf(',');
if(commaPos != -1)
str = str.Substring(0, commaPos)
I'm assuming you're working with a string to begin with. Ideally, if you're working with a number to begin with, like a float or double, you could just cast it to an int, then do myInt.ToString() like:
myInt = (int)double.Parse(myString)
This parses the double using the current culture (here in the US, we use . for decimal points). However, this again assumes that your input string is can be parsed.
String.Format("{0:0}", 123.4567); // "123"
If your initial value is a decimal into a string, you will need to convert
String.Format("{0:0}", double.Parse("3.5", CultureInfo.InvariantCulture)) //3.5
In this example, I choose Invariant culture but you could use the one you want.
I prefer using the Formatting function because you never know if the decimal may contain 2 or 3 leading number in the future.
Edit: You can also use Truncate to remove all after the , or .
Console.WriteLine(Decimal.Truncate(Convert.ToDecimal("3,5")));
Use:
public static class StringExtensions
{
/// <summary>
/// Cut End. "12".SubstringFromEnd(1) -> "1"
/// </summary>
public static string SubstringFromEnd(this string value, int startindex)
{
if (string.IsNullOrEmpty(value)) return value;
return value.Substring(0, value.Length - startindex);
}
}
I prefer an extension method here for two reasons:
I can chain it with Substring.
Example: f1.Substring(directorypathLength).SubstringFromEnd(1)
Speed.
You could use LastIndexOf and Substring combined to get all characters to the left of the last index of the comma within the sting.
string var = var.Substring(0, var.LastIndexOf(','));
You can use TrimEnd. It's efficient as well and looks clean.
"Name,".TrimEnd(',');
Try the following. It worked for me:
str = str.Split(',').Last();
Since C# 8.0 it has been possible to do this with a range operator.
string textValue = "2223,00";
textValue = textValue[0..^3];
Console.WriteLine(textValue);
This would output the string 2223.
The 0 says that it should start from the zeroth position in the string
The .. says that it should take the range between the operands on either side
The ^ says that it should take the operand relative to the end of the sequence
The 3 says that it should end from the third position in the string
Use lastIndexOf. Like:
string var = var.lastIndexOf(',');

Copy first few strings separated by a symbol in c#

I have a string consist of integer numbers followed by "|" followed by some binary data.
Example.
321654|<some binary data here>
How do i get the numbers in front of the string in the lowest resource usage possible?
i did get the index of the symbol,
string s = "321654654|llasdkjjkwerklsdmv"
int d = s.IndexOf("|");
string n = s.Substring(d + 1).Trim();//did try other trim but unsuccessful
What to do next? Tried copyto but copyto only support char[].
Assuming you only want the numbers before the pipe, you can do:
string n = s.Substring(0, d);
(Make it d + 1 if you want the pipe character to also be included.)
I might be wrong, but I think you are under the impression that the parameter to string.Substring(int) represents "length." It does not; it represents the "start-index" of the desired substring, taken up to the end of the string.
s.Substring(0,d);
You can use String.Split() here is a reference http://msdn.microsoft.com/en-us/library/ms228388%28VS.80%29.aspx
string n = (s.Split("|"))[0] //this gets you the numbers
string o = (s.Split("|"))[1] //this gets you the letters

Categories