I'm trying to understand CompareTo() in C# and the following example made me more confused than ever. Can someone help me understand why the result for the 3rd variation is 1? 2nd word in the sentence "Hello wordd" is not the same as str1 "Hello world" so why am I getting 1? Shouldn't I get -1?
static void Main(string[] args)
{
string str1 = "Hello world";
Console.WriteLine(str1.CompareTo("Hello World"));
Console.WriteLine(str1.CompareTo("Hello world"));
Console.WriteLine(str1.CompareTo("Hello wordd"));
}
Results: -1, 0, 1
If the strings match, then CompareTo() gives 0. If they don't match, it gives a positive or negative number depending on which string comes first alphabetically.
In your example, both the results 1 and -1 indicate the strings do not match, while 0 indicates the strings match.
It looks like you are using it to determine equality and not to sort. If this is the case, then you should use Equals() instead.
The String.CompareTo method compares this instance with a specified object or String and returns an integer that indicates whether this instance precedes.
if the return value is Less than zero: This instance precedes value.
if the return value is Zero: This instance has the same position in the sort order as value.
if the return value is Greater than zero: This instance follows value.
-or-
value is null.
Related
if I assing a string with
string = "12";
and check its value with
Console.Write(string[0] + string[1]);
it returns 12 as intended.
but if I assign string[0] to an int array via
int[0] = string[0];
and check its value via
Console.Write(int[0]);
it returns 49.
even if I used Convert.ToInt32() while assigning, it still returned 49.
the code
the result
Can you help me out here?
It is returning 49 because you are trying to convert the value 1 to integer and the ASCII value of 1 is 49. if you want to print the value as 1 to need to use string only, then you can use the code similar to this int.Parse(stringValue); or you can use TryParse method as well.
You are casting the char '1' into an int which works. Which according to the ASCII table is 49.
For example assigning 'A' to int[0] would set its value to 65.
You must just use int.Parse().
using System;
public class Program
{
public static void Main()
{
string t1, t2;
t1 = "Test";
t2 = "test";
Console.WriteLine(t1.CompareTo(t2)); //prints 1, expected was -1
}
}
So, it says that CompareTo() is supposed to return 1 - if it's greater than, -1 if it's less than or 0 if it's equal to the other string. In this example I am comparing "Test" with "test". As I understood, in ASCII, 'A' < 'a'.
So why does it say that t1 is greater if the only difference is first letter, and by ASCII, it should be smaller. Thanks.
The default C# string comparison (as in, if you don't specify it yourself anywhere) is a culture-aware comparison, and the rules depend on your computer's culture.
If you want to use ordinal comparison (ie ASCII as you call it, though C# strings are Unicode), you can use this instead:
Console.WriteLine(string.Compare(t1, t2, StringComparison.Ordinal));
Also note that the specification requires a negative, zero or positive result, not specifically -1. The command above will return -32 for example.
Sample code to illustrate:
int res1 = "a".CompareTo("A"); // res1 = -1
int res2 = "ab".CompareTo("A"); // res2 = 1
I'm seeing res1 = -1, and res2 = 1 at the end, which was a bit unexpected.
I thought res1 would return 1, since on an ASCII chart "A" (0x41) comes before "a" (0x61).
Also, it seems strange that for res2, the length of the string seems to make a difference. i.e. if "a" comes before "A" (as res1 = -1 indicates), then I would have thought that "a"withAnythingAfterIt would also come before "A"withAnythingAfterIt.
Can someone shed some light?
Thanks.
This is the expected behavior. String.CompareTo(string) does a culture sensitive comparison, using its sort order. In fact it calls CultureInfo to do the job as we can see in the source code:
public int CompareTo(String strB) {
if (strB==null) {
return 1;
}
return CultureInfo.CurrentCulture.CompareInfo.Compare(this, strB, 0);
}
Your current culture puts 'A' after 'a' in the sort order, since it would be a tie, but not after 'ab' since clearly 'ab' comes after either 'a' or 'A' in most sort orders I know. It's just the tie breaking mechanism doing its work: when the sort order would be the same, use the ordinal value!
From MSDN
Definition
Compares this instance with a specified Object and indicates whether
this instance precedes, follows, or appears in the same position in
the sort order as the specified Object.
Note
The CompareTo method was designed primarily for use in sorting or
alphabetizing operations. It should not be used when the primary
purpose of the method call is to determine whether two strings are
equivalent. To determine whether two strings are equivalent, call the
Equals method.
CompareTo is an instance method.
If the first string is bigger, the result is 1. If the first string is smaller, the result is -1. If both strings are equal, the result is 0. The number essentially indicates how much "larger" the first string is.
Console.WriteLine("a".CompareTo("A")); // -1
Console.WriteLine("ab".CompareTo("A")); // 1
Console.WriteLine("a".CompareTo("a")); // 0
Console.WriteLine("ab".CompareTo("AB")); // -1
Console.WriteLine("A".CompareTo("a")); // 1
Console.WriteLine("AB".CompareTo("ab")); // 1
Console.WriteLine("A".CompareTo("A")); // 0
I have the Following Code
CASE 1
string string1 = "pankaj";
string string2 = "pankaj";
Console.WriteLine(string1 == string2); // output TRUE
CASE 2
object obj1 = "pankaj";
object obj2 = "pankaj";
Console.WriteLine(obj1==obj2); // Output TRUE
CASE 3
object againObject1 = 2;
object againObject2 = 2;
Console.WriteLine(againObject1==againObject2); // Output FALSE
as string and object are both reference type and for reference type I learned that equality operation checks if they hold the same address, in above two case why its comparing value instead of references.
what is more confusing is the behavior of equality operator for object type in case 2 and case 3 for string type it computes true and for integers its return false.
String equality is different. Among many other things...
Example 1 and 2 will in both cases return the exact same object - the INTERNED string ("pankaj" exists only once after internalization, and all constant strings are internalized).
Example 3 has 2 boxed objects without any optimization - so 2 boxes around a value type.
Strings are objects and integers also are, but the later are type values. So the example 3 is pointing to two different places in memory and you are trying to compare their addresses by boxing them on objects.
using:
object1==object2
isn't comparing the content of the object, instead it's a comparison of the storage-address,
if the object is comparable use object1.equals(object2)
The String class has overridden operator == so as to implement comparison by value, and the Int32 class has not.
This question already has answers here:
Why does "abcd".StartsWith("") return true?
(11 answers)
Closed 9 years ago.
I jumped into this accidentally and have no clue as to why this is happening
string sample = "Hello World";
if (sample.Contains(string.Empty))
{
Console.WriteLine("This contains an empty part ? at position " + sample.IndexOf(string.Empty));
Console.WriteLine(sample.LastIndexOf(string.Empty));
Console.WriteLine(sample.Length);
}
Output
This contains an empty part ? at position 0
10
11
I am happy with the last part, but i have no idea why this is evaluated true. Even Indexof and LastIndexOf have separate values.
Could anyone help me out on why is this so?
EDIT
I believe this is a bit relevant to my question and would be also helpful to those who stumble upon this question.
See this SO link: Why does "abcd".StartsWith("") return true?
From msdn for IndexOf
If value is String.Empty, the return value is 0.
For LastIndexOf
If value is String.Empty, the return value is the last index position in this instance.
For Contains
true if the value parameter occurs within this string, or if value is the empty string ("");
Question: Does the string "Hello World" contain String.Empty?
Answer: Yes.
Every possible string contains String.Empty, so your test is correctly returning true.
If you are trying to test if your string is empty, then the following code is what you want
if (string.IsNullOrEmpty(sample))
{
}
This is documented in the String.Contains Method:
Return Value
Type: System.Boolean
true if the value parameter occurs within this string, or if value is the empty string (""); otherwise, false.
And in String.IndexOf Method
If value is String.Empty, the return value is 0.
And in LastIndexOf Method
If value is String.Empty, the return value is the last index position in this instance.