Exception thrown out with string function replace in c# - c#

Following code will cause exception:
string IDs = "";
IDs = IDs.Replace("", "");
Why?

It's right in the documentation for string.Replace(). If you try to replace with the "oldValue" parameter as an empty string, it throws an exception.
Exception Condition
ArgumentException oldValue is the empty string ("").
If you think about it, what are you actually trying to do when you try to find an empty string in another string and replace it with something? Conceptually it doesn't make sense.

String cannot be of zero length.
Probably explains why.

It throws an exception because "" would never be found.
It can be argued that both "" does not exist within a string, or that there are an infinite number of "" within any string.
It just plain don't make sense to replace an empty string with an empty string.

I'd guess it's because string.Replace() loops through characters from 0 to its .Length. Obviously this would just skip the loop as there would be nothing to loop through, perhaps they threw a throw in there out of paranoia?

Well, what do you expect?
You want to replace nothing with nothing? What exactly do you want to do?
Let's say the old string was "ABC", what would you want it to be after your call to Replace?
In this particular case, the exception thrown is an ArgumentException, and the text of it is that "String cannot be of zero length".
So, the criteria of calling the .Replace method is that what you want to replace is not a string without contents.
Let's check the documentation of String.Replace(String, String):
Under Exceptions it says:
ArgumentNullException, if oldValue is a null reference (Nothing in Visual Basic).
or
ArgumentException, if oldValue is the empty string ("").
So everything is behaving like expected.

The reason for this is that conceptually, every string contains an infinite number of empty strings at the start, at the end, and between characters. (This is why foo.IndexOf("") will always return 0 for any string foo.) Replacing all the infinite amount of empty strings with something else makes no sense as an operation.

Related

string.IsNullOrEmpty & string.IsNullOrWhiteSpace return false for empty string

I have run into a curious case where a block of code that is designed to weed out blank strings, periods dashes and the like after a paragraph of text is processed from the MSFT Azure Phrase Breaker. I could use help figuring out how to debug the issue.
The following block of code returns true when given a value of "". Obviously the expectation is the method should return false after the first if statement. Out of 899 phrases to be looked at, only two seem to have this problem. Happens on another machine as well.
public static bool IsSentenceTranslatable(string sentence)
{
string trimmedSentence = sentence.Trim();
if (string.IsNullOrEmpty(trimmedSentence) || string.IsNullOrWhiteSpace(trimmedSentence))
{
return false;
}
switch (trimmedSentence)
{
case " ":
case ".":
case "-":
case "ยท":
return false;
}
return true;
}
Here is a snapshot of the debugger.
Could it be a bug in Visual Studio or .NET? I tried using the various visualizers, but still couldn't see anything in the box. .NET 4.5 C# 7.3
Try to get the string's byte representation. I suspect that it actually contains some character which is invisible in VS debugger but doesn't count as a whitespace.
See this questions for hints:
Invisible characters - ASCII
Converting string to byte array in C#
UPD: since your Watch window shows that after the call string trimmedSentence = sentence.Trim() you have trimmedSentence.Length == 1, I'd upgrade my suspicion to certainty.
As stated in my comment, in that screenshot you can see that trimmedSentence.Length is 1, therefore it's not empty, and its contents is definitely not a standard space. If the string appears empty, it's because it has one of those so-called invisible characters. To check what your string has, you can directly access that character by doing trimmedSentence[0].
If that character will appear often, you might want to consider doing this:
string trimmedSentence = sentence.Trim().Replace("<this special character>", "");
Alternatively, you can create that replaceable string from the Unicode value by doing Char.ConvertFromUtf32(yourCharCode).ToString(). You cannot use the Replace overload that uses character parameters, as there is no "empty" character, only an empty string. You should be able to get this value while debugging. Or if necessary, by doing (int)trimmedSentence[0].

replace string with double quotes

I want to replace, from a JSON file :"[" to :["
The below runs but without delivering the expected.Any clues?(I looked in similar questions, but I was more confused)
string contenty = contentx.Replace(":"["",":["");
return contentx;
You're returning contentx instead of contenty. contenty is the variable that has the new string.
First you have to escape the double quotes with \"
Then you have to return the "return value" of the expression in the same variable, or simply use one return statement:
return contentx.Replace(":\"[\"", ":[\"");
Try it like this (you have some issues with the double quotes in a string):
return contentx.Replace(#":""[""", #":[""");
Another option is:
return contentx.Replace(":\"[\"", ":[\"");
This will make sure that the character escaping goes well and your string is replaced properly. Moreover, as Equalsk showed in his comment, this will also solve the problem of returning the wrong variable and creating an unnecessary variable.

How do get the first occurrence of a char in Substring

I'm trying to get the first occurrence in my substring start point:
string dir = Request.MapPath(Request.ApplicationPath) + "\\App_GlobalResources\\";
foreach (var file in Directory.EnumerateFiles(dir, "*.resx"))
{
ddlResources.Items.Add(new ListItem { Text = file.Substring(firstoccuranceof("."), file.LastIndexOf(".")), Value = file });
}
if I do file.Substring(file.IndexOf("."), file.LastIndexOf(".")) I get an error
To answer your actual question - you can use string.IndexOf to get the first occurrence of a character. Note that you'll need to subtract this value from your LastIndexOf call, since Substring's second parameter is the number of characters to fetch, not a start and end index.
However... Instead of parsing the names, you can just use Path.GetFilenameWithoutExtension to get the filename directly.
First occurence
String.IndexOf('.')
Last occurence
String.LastIndexOf('.')
Use IndexOf and LastIndexOf string methods to get index of first and last occurrence of "search" string. You may use System.IO.Path.GetExtension(), System.IO.Path.GetFileNameWithoutExtension(), and System.IO.Path.GetDirectoryName() methods to parse the path.
For instance,
string file = #"c:\csnet\info.sample.txt";
Console.WriteLine(System.IO.Path.GetDirectoryName(file)); //c:\csnet
Console.WriteLine(System.IO.Path.GetFileName(file)); //info.sample.txt
Console.WriteLine(System.IO.Path.GetFileNameWithoutExtension(file));//info.sample
Console.WriteLine(System.IO.Path.GetExtension(file)); //.txt
file.IndexOf(".")
Should get you the first occurence of ".". Otherwise it will return -1 if not found.
I think that in your particular case you are NOT trying to get IndexOf... Instead you need to use 0 because you are trying to create a key based on filename if understand correctly:
`ddlResources.Items.Add(new ListItem(file.Substring(0, file.LastIndexOf(".")), file ));`
Also, you have '{}' in there as in new ListItem { ... } which is also going to cause a syntax error... Anyhow have a look..
Because the original question is marked with the [regex] tag, I'll provide the following solution, however the best answer for simple parsing of paths using .NET is not by regex.
//extracts "filename" from "filename.resx"
string name = Regex.Match("filename.resx", #"^(.*)\..+?$").Groups[1].Value;
Use an answer that relies on the Path class instead, for simplicity. Other answers contain that info.
Here you go!)
Using a string variable type
int index = str.IndexOf(#"\");
"C:\Users\somebody\Desktop\aFolder\someFile"
https://www.peachpit.com/articles/article.aspx?p=31938&seqNum=12#:~:text=To%20find%20the%20first%20or,string%20you%20are%20searching%20for.

about string removing in C#

Whats is correct to do?
check if exists, then remove?
var input = "foo #main baa";
if(input.Contains("#main")) {
input = input.Replace("#main", "");
}
or just:
input = input.Replace("#main", "");
Well, this seem a simple question,but I really want know.
Thanks in advance.
The Contains check actually just makes your code slower.
Remove it.
The Contains call needs to loop through the string until it finds #main.
The Replace call then needs to do the same exact loop (it can't remember it from the Contains call).
This is a Shlemiel the Painter's algorithm.
Replace can handle strings with zero or more occurrences of the search string, so you don't need the check.
Just do the replacement - if it's not there, nothing should happen.
Just make the call to Replace(). If the substring isn't found nothing happens and you avoid an additional call to Contains().
I would do this:
input = input.Replace("#main", "").Replace(" "," ");
To remove any double spaces.
Just remove it. The only thing to check is if the string is null or not.

Is it better to use "0" concatenation in Convert.ToInt32() function call

Is better to use the below statement
Convert.ToInt32("0" + stringValue)
If not then why?
I know that it is better to user int.TryParse() function, which is better, but what about the above statement.
Better than what?
Personally, I think that using Convert.ToInt32("0" + stringValue) is an anti-pattern.
It doesn't provide anything useful, since:
A positive integer will still result in the same value.
If you pass it a negative number, it will throw.
It doesn't add any extra error checking
It DOES create an extra string concatenation, which is not used for anything, reducing performance for no reason
It adds extra complexity for no reason.
Just use Convert.ToInt32(stringValue) directly, or int.TryParse if you don't want to have exception handling in place.
The only case when that would have any use is if the string variable is a null reference. Concatenating with a zero character is totally pointless, though. As we are only after the null check performed by the string concatenation, a better version would concatenate with an empty string instead, as that doesn't break for negative values:
Convert.ToInt32(String.Empty + stringValue)
A better solution as it doesn't do a string concatenation:
Convert.ToInt32(stringValue ?? String.Empty)
An even better solution would be to check for the null value first, so that you don't have to parse the known string:
stringValue == null ? 0 : Convert.ToInt32(stringValue)

Categories

Resources