tags:

views:

1197

answers:

5

I was thinking to a solution to calculate length of string in c# without using Length property.

I thing which I can think of is getting this done is

Program is in C#

public static int strlen (string s)  
{   
    string temp = s + '/0';  
    char [] c = temp.ToCharArray();    
    int length = 0;    
    while (c[length]!='/0') length++;  
    length--;  
    return length;  
}

but this is very naive programming, it also uses 1 extra temp variable Can you guys think of better solution than this?

+3  A: 
public static int strlen2 (string s) {
    int length = 0;
    foreach (char c in s) length++;
    return length
}

I am not sure what is the point of doing that though.

leiz
+2  A: 
John T
+5  A: 

The issue is the way strings are stored in C#. While in some languages it takes computation to figure out how long a string is, in C#, the only way to figure out the length of a string is through its Length property. If you thing about how strings are stored, there is an array of character, and a Length. Now, the strings are not null-terminated, so you need the Length field to know how much of the array you can access before you start reading memory that isn't part of the array. You can hide what you are doing through abstraction though. For example you can call the ToCharArray function, but in order to generate the null-terminated string which you use, it first has to access the Length value to allocated the right amount of memory for the char[] array and copy the right amount of characters. Or you could use a for each (char c in s) length++;

as somebody else suggested. This is another way to hide the fact you are accessing the Length value. In order to iterate over the characters in this way, you must first access the Length value to see how many characters you are iterating over. Whether it does this in a library call, or it compiles it away to a different construct, I am not sure, but the end result is the same.

Jeremybub
.NET strings *are* null terminated. The terminating character is somewhat transparent though.
arul
@anul - whether the memory ends in a 0 byte is irrelevant. They can *contain* null characters. This will print 3:char nul = '\0';string embeddedNull = "1" + nul + "3";Console.WriteLine(embeddedNull.Length);
TrueWill
+3  A: 

I think to optimize a bit on Leiz's answer, I would use pre-increment instead of post increment on line 3 to read:

foreach(char c in s) ++length

Which would squeeze a tiny bit of performance out of it.

Nadewad
No it wont the bytecode would be the same. increment length. If the ++ were part of an expression then different bytecodes would be generated but in your example the result would be the same.
mP
Wouldn't using the preincrement not waste time creating the temporary variable incrementing the original then returning the temp?
Nadewad
preincrement means increment previous to returning the value... thus no temp...
dionadar
+4  A: 

You can get the length at O(1) speed using unsafe code, since C# strings are prefixed with their length - this is probably what the get_Length function does internally (and thats why you should use the built-in way instead of writing your own):

public static unsafe int strlen(string s) 
{
    if(s == null) {
        // Handle the error here
    }

    int length = 0;

    fixed(char *pStr = s) {
        length = *(((int *)pStr) - 1);
    }

    return length;
}

Or if you prefer more old schoolish approach:

public static unsafe int strlen(string s) 
{
 if(s == null) {
  // Handle the error here
 }

 int length = 0;

 fixed(char *pStr = s) {
  char *pEnd   = pStr; 
  while(*pEnd++ != '\0'); 
  length = (int)((pEnd - pStr) - 1);            
 }

 return length;
}
arul
is internally string null terminated in c#?....In not than how can you use the following statement while(*pEnd++ != '\0'); ?
Learner
Yes, .NET strings are basically BSTR's - length prefixed, double-byte and null terminated.
arul
The "old school" approach will not work. I just tried the second example with "d\0g" (embedded null) and it returned 1.
TrueWill
That is correct. You just ***can not*** embed null character into a null terminated string and expect the algorithm to magically pick it up.
arul
@arul - My point is that it **cannot** be safely treated as a null terminated string, since a .NET string permits embedded nulls (and, when using the standard properties/methods, still works properly). You are making an assumption (no embedded nulls) that is not always valid in .NET.
TrueWill