如何在c#中实现strlen()?

Lea*_*ner 0 c# string

我正在考虑一个解决方案来计算c#中的字符串长度而不使用Length 属性.

我能想到的事情就是这样做

程序在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;  
}
Run Code Online (Sandbox Code Playgroud)

但这是非常天真的编程,它还使用了1个额外的临时变量你能想到更好的解决方案吗?

Jer*_*wen 8

问题是字符串存储在C#中的方式.虽然在某些语言中需要计算来计算字符串的长度,但在C#中,计算字符串长度的唯一方法是通过其Length属性.如果关于字符串的存储方式,则有一个字符数组和一个Length.现在,字符串不是以空值终止的,因此您需要使用 "长度"字段来了解在开始读取不属于数组的内存之前可以访问的数组量.您可以通过抽象隐藏您正在做的事情.例如,您可以调用ToCharArray函数,但是为了生成您使用的以null结尾的字符串,它首先必须访问Length值以为char []数组分配适当的内存量并复制正确的数量字符.或者你可以使用每个(char c in s)长度++;

正如其他人所说的那样.这是隐藏您访问Length值的另一种方法.为了以这种方式迭代字符,您必须首先访问"长度"值以查看要迭代的字符数.无论是在库调用中执行此操作,还是将其编译为不同的构造,我都不确定,但最终结果是相同的.

  • @anul - 内存是否以0字节结尾是无关紧要的.它们可以*包含*null字符.这将打印3:char nul ='\ 0'; string embeddedNull ="1"+ nul +"3"; Console.WriteLine(embeddedNull.Length); (2认同)

aru*_*rul 5

您可以使用不安全的代码以O(1)速度获得长度,因为C#字符串以其长度为前缀 - 这可能是get_Length函数在内部执行的操作(这就是为什么您应该使用内置方式而不是编写自己的方式):

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;
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您更喜欢更古老的学校方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

  • @arul - 我的观点是它不能被安全地视为空终止字符串,因为.NET字符串允许嵌入的空值(并且,当使用标准属性/方法时,仍然可以正常工作).您正在做一个在.NET中并不总是有效的假设(没有嵌入的空值). (2认同)