Suche C# Äquivalente zur strstr(), strncmp(), ...



  • Ich bin neu in der C# Welt. Ich möchte einen String relativ effizient verarbeiten. Hierbei muss ich für einen String feststellen, ob Datensätze vorhanden sind und diese interpretieren.

    Unter C arbeitete ich folgendermaßen:

    const char* FindBlock(const char* String, const char* Name)
    {
      const char* s = String;
      const char* sb;	
      const char* Block;
    
      do
      {
        // Suche im String das Startzeichen des Blocks (= "|")
        sb = strstr(s, "|");
        if (sb == null)
          return NULL;
        Block = sb; // speichere potenziellen Block
        // Überlese die nächsten zwei Zeichen (sind uninterresant)
        sb++;
        if (sb == 0)
          return NULL;
        sb++;
        if (sb == 0)
          return NULL;    
        // String sb zeigt nun auf den Blocknamen ->
        // Überprüfe ob dieser mit dem angegebenen Namen identisch ist.
        // Ist dieser identisch, liefere den Block zurück.
        if (strncmp(sb, Name, sizeof(Name) == 0)
          return Block;
        s = Block + 1;
      } while (s != 0)
    }
    

    Unter C# kopiere ich mir aktuell den Wolf:

    private string FindBlock(string s, string Name)
    {
      string s1, s2;
    
      foreach (string Block in s.Split(Delim))
      {
        if (Block[0] != Delim[0])
          continue;
        if (Block.Length < 2)
          continue;
        s1 = Block.Substring(2);
        s2 = s1.Substring(0, Name.Length);
        if (s1 == s2)
          return Block;
      }
      return "";
    }
    

    Wie kann man das effizienter machen?



  • Strings sind immutable, du kannst keinen Substring haben ohne eine Kopie.
    Geh über Indices, ist zwar etwas mehr Aufwand, sollte aber deutlich effizienter sein. 😉

    static string FindBlock(string Str, string Name)
            {
                int pos = -1;
    
                while (true)
                {
                    pos = Str.IndexOf('|', pos + 1);  // Suche im String das Startzeichen des Blocks (= "|") 
    
                    if (pos == -1)
                        return null;
                    int posBlock = pos;
                    pos += 2; // Überlese die nächsten zwei Zeichen (sind uninterresant) 
                    if (pos >= Str.Length)
                        return null;
    
                    if (String.Compare(Str, pos, Name, 0, Name.Length) == 0)
                    {
                        int endBlock = Str.IndexOf('|', posBlock + 1);
                        if (endBlock == -1)
                            endBlock = Str.Length;
                        return Str.Substring(posBlock, endBlock - posBlock);
                    }
    
                }
            }
    

    PS, dass

    if (strncmp(sb, Name, sizeof(Name) == 0)
          return Block;
    

    Stuss ist weißt du?
    Es sollte

    if (strncmp(sb, Name, strlen(Name)) == 0)
          return Block;
    
    //oder
    if (strncmp(sb, Name, strlen(Name) + 1) == 0)
          return Block;
    

    heißen.
    Bei meinem Compare gibt es noch Probleme wenn der Name z.B. "ABC" ist, der Block aber "ABCDE" heißt. Keine Ahnung ob und wie das Problem gelöst sein soll. 😃



  • Danke für die Infos. 🙂

    String.Compare() und string.IndexOf() sind genau die Funktionen, welche ich gesucht habe.



  • Und die hast du über die MSDN nicht gefunden 😕

    Ich pack das grad überhaupt nicht.



  • Naja, ganz einfach. Ich habe einfach falsch gesucht.

    Im C# Buch habe ich nur wenige String Operationen gefunden. In der Code Completion von VS habe ich zwar eine CompareTo() Funktion gefunden, aber keine Compare() Funktion. Dafür habe ich eine Menge von <> Funktionen gefunden, welche mich verwirren, mich aber an <algorithm.h> erinnerten. Naja, und meine Hilfe lotste mich erst zu DataItemType. Über die Suchen Funktion fand ich diverse XML String Operationen.

    Erst auf dem zweiten Blick entdecke ich nun die C# String Klasse über Beispielsweise "String Construktor (System)". Ich muss wohl als Suchbergiff "C# string" eingeben und nicht "string".



  • Hallo,

    kannst du mal einen Beispiel String geben? Die Sache klingt für mich so, als wenn man das einfach mit einer regex lösen kann, die dann die Blöcke zurück geben kann.

    Grüße,


Log in to reply