Diverse Fragen



  • Hi com

    Ich wollte mal aus reiner Neugier ein paar Fragen stellen, die ich leider sonst nirgends finden konnte (sprich unter google und co.)

    1. Wenn ich ein String (naje eher Array of char) definiere und gleichzeitig einen String zuweisen möchte muss ich stehts darauf auchten, das ich 2 Elemente mehr hab als Zeichen zum einlesen:

    z.B char i[3] = "ab";

    klar das eine ist für das Terminalflag aber woführ ist dan das andere? bzw ist das immer so bezogen auf dem gesamten Arbeitsspeicher?

    2. Wo wir auch schon beim Terminalflag sind ich hab immer ein Problem bei Stringverarbeitungen das sobalt ich mit meinem Zeiger an das Terminalflag komme (naja brauch ne abbruchbedingung), meine Schleife dan automatisch beendet ist, (und dabei möchte ich eigendlich gerne dass er das noch ein letztes mal macht):

    #include <stdio.h>

    bool CheckRegExp(char *SString,char *regexp)
    {
    const char *SBEGIN = regexp;
    SString--;
    do
    {
    SString++;
    if (regexp == '\0')
    {
    return 1;
    break;
    }
    else if (*SString == *regexp)
    {
    regexp++;
    }
    else
    {
    regexp = (char
    )SBEGIN;
    if (*SString == *regexp)
    {
    regexp++;
    }
    }
    }
    while (*SString != '\0');
    return 0;
    }

    void main(void)
    {
    char string[] = "ahslfkla";
    char stringg[] = "a";
    char str;

    if (!CheckRegExp(string,stringg))
    {
    printf("Not Found");
    }
    else
    {
    printf("Found");
    }
    }

    Gibt es also noch ne andere möglichkeit, ohne den Zeiger extra aufs nachbaland starren lasen zu müssen?

    3. Wo wir auch schon beim Zeigern sind:) gitbt es, auch bezogen auf dem Fall ne möglichkeit die größe des Array (oder viel eher die anzahl der vorhandenen Zeichen) zu ermitteln, ohne noch nen Parameter dazu erfinden zu müssen?

    und noch zum schluss 4: Gibt es ne möglichkeit, ein wenig mit den Elementen zu spielen sprich löschen, pushen popen?

    Danke im voraus



  • gehört eig. ins ANSI-C, aber naja...

    Also zu 1.)

    char string[3] = "ab";
    

    Das Char-Array ist drei Zeichen lang. [0] = 'a'; [1] = 'b'; [2] = '\0';
    Wo da deine zwei überflüssigen Zeichen sein sollen hab ich nicht verstanden.

    zu 2.) ohne Syntax-Coloring les ich mir das nicht durch 😉

    zu 3.) man kann nur die Größe eines statischen Array bestimmen. Beispiel:

    char string[] = "Hallo Welt!";
    unsigned int size = sizeof (string) / sizeof(string[0]);
    

    Sobald du das Array dynamisch anlegst oder an eine Funktion übergibst, geht diese Information verloren, da sizeof() dann die Größe des Zeiges liefert. AFAIK gibt es in C++ die Möglichkeit ein Array per Referenz zu übergeben und so diese Info zu erhalten, aber denke mal du proggst C.

    zu 4.) Nein. Musst schon selber was programmieren oder was vorgefertigtes nehmen (zB ne Liste).

    Gruß
    Don06



  • Hi,

    Sirius Black schrieb:

    klar das eine ist für das Terminalflag aber woführ ist dan das andere? bzw ist das immer so bezogen auf dem gesamten Arbeitsspeicher?

    Das ist eine Fehlannahme, die zunächst viele Anfänger haben. In C++ beginnt alles bei 0 an zu zählen, nicht wie wir Menschen bei 1. Das bedeutet konkret, dass dein Array mit drei Elementen (array [3]) folgenden Inhalt hat:

    [0][1][2]
    a b \n

    Erstes und zweites Element beinhalten die beiden Buchstaben "ab", und das dritte Element beinhaltet die Terminierung. Das macht dann insgesamt drei Elemente, weshalb man sich bei der Größenangabe immer auf diese Denkweise beziehen soll. Wenn du z.B. auf array [3] zugreifen möchtest, gibt das eine Access Violation und führt somit meistens einen Programmabsturz nach sich, weil du das dritte Element im Prinzip nicht angefordert hast, sondern lediglich ein Array mit drei Elementen. Verstanden? 🙂

    Zu Frage 2., ohne mir deinen Code genau angeguckt zu haben, hast du mit einem C++ Compiler kompiliert, da im C Standard noch kein bool existierte. Weshalb nimmst du dann nicht einfach std::string, das vereinfacht dir die ganze Sache um einiges.

    Zur dritten Frage, die Größe eines Arrays kannst du folgendermaßen ermitteln:

    int ArraySize = sizeof (DeinArray) / sizeof (char);
    

    Mit der std::string Klasse von C++ müsste man nur DeinArray.size () schreiben 😉

    Dann zur nächsten Frage, ja natürlich ist es möglich solche Operationen auf Arrays anzuwenden. Allerdings ist das mit relativ viel Aufwand verbunden, in C++ gäbe es hierfür std::vector<>. Wenn du z.B. einem bestehenden Array ein weiteres Element hinzufügen möchtest, musst du erstmal ein neues Array mit der Größe des alten +1 anlegen, den Inhalt des Alten ins Neue kopieren, und dein neues Zeichen anhängen. (Dürfte soweit selbsterklärend sein). Löschen kannst du auch einzelne Elemente, indem du ein neues Array mit der Größe des Alten -1 anlegst, und dann anschließend durch das neue Array mithilfe einer for Schleife durchiterierst, und die Elemente des alten Arrays einzeln reinkopierst. Sobald der Index des zu löschenden Elements erreicht ist, setzt du einfach ein continue, und die Schleife kopiert es nicht mit rein.

    Achja, noch was, und tausch das void main durch int main aus, so wird dein Code etwas portabler... (Ironisch ausgedrückt, ist aber kein Standard C++)

    Servus.



  • Don06 schrieb:

    char string[] = "Hallo Welt!";
    unsigned int size = sizeof (string) / sizeof(string[0]);
    

    Sobald du das Array dynamisch anlegst oder an eine Funktion übergibst, geht diese Information verloren, da sizeof() dann die Größe des Zeiges liefert.

    falls das array immer nullterminierte strings enthält, kann man die länge mit strlen() wieder gewinnen, aber leider nicht immer die tatsächliche grösse des arrays, nur die länge des strings darin.

    Don06 schrieb:

    AFAIK gibt es in C++ die Möglichkeit ein Array per Referenz zu übergeben und so diese Info zu erhalten...

    nö, ein char* oder char[] führt keine längenangabe mit sich. in C++ könnte man stattdessen ein std::string-objekt benutzen, das sich die länge merkt.
    🙂



  • Hi zunächtmahl und danke für die noch späte antwort;)

    mikey schrieb:

    Das ist eine Fehlannahme, die zunächst viele Anfänger haben. In C++ beginnt alles bei 0 an zu zählen, nicht wie wir Menschen bei 1. Das bedeutet konkret, dass dein Array mit drei Elementen (array [3]) folgenden Inhalt hat:

    [0][1][2]
    a b \n

    Ehem ja ich weis sooo Anfänger bin ich noch nicht aber ich festh nur nicht wieso mein mein Compiler bei

    char str[2] = "ab";
    

    Eine Fehlermeldung ausgibt oder ligt genau das am Access Violation, hat dan jedes Array of char was ich statisch (oder dynamisch auch?)erzeuge noch 1 unbesetztes Element hintendran?

    und noch mal im algemeinem ja es handelt sich um C++ Code soll aber doch später c sein (in der Arbeit benutze ich notgedrungen nen C-Compiler mit Benutzerdefinierten Bool;)

    #include <stdio.h>
    
    bool CheckRegExp(char *SString,char *regexp)
    {
      const char *SBEGIN = regexp;
      SString--;
      do
      {
        SString++;
        if (*regexp == '\0')
        {
          return 1;
          break;
        }
        else if (*SString == *regexp)
        {
          regexp++;
        }
        else
        {
          regexp = (char*)SBEGIN;
          if (*SString == *regexp)
          {
            regexp++;
          }
        }
      }
      while (*SString != '\0');
      return 0;
    }
    
    void main(void)
    {
      char string[] = "ahslfkla";
      char stringg[] = "a";
      if (!CheckRegExp(string,stringg))
      {
        printf("Not Found");
      }
      else
      {
        printf("Found");
      }
      scanf("%c",&string);
    }
    

    Ach wo schon Cracks dabei sind, wie beugt man Programmabstürze bei zu langen Strings vor? ja ich hab was von allokieren gehöhrt aber der dynamische speicher is doch auch voll wenn man nicht genau weis wie viele zeichen als input kommen (z.B von einer Datai, die man Zeilenweise einlesen möchte)

    Gruß Sirius Black



  • Apeman schrieb:

    Don06 schrieb:

    AFAIK gibt es in C++ die Möglichkeit ein Array per Referenz zu übergeben und so diese Info zu erhalten...

    nö, ein char* oder char[] führt keine längenangabe mit sich. in C++ könnte man stattdessen ein std::string-objekt benutzen, das sich die länge merkt.
    🙂

    Ein char* natürlich nicht ein char[] jedoch schon:

    #include <iostream> 
    
    template <class T, size_t N>
    size_t getStaticArraySize(T (&arr)[N])
    {
    	return N;
    }
    
    int main()
    {
    	char myString[] = "Hallo Welt!";
    	std::cout << getStaticArraySize(myString) << std::endl;
    
    	return 0;
    }
    

    Solange man die Arrays per Referenz übergibt bleiben die Typinformation (weitesgehend) erhalten.

    Gruß
    Don06



  • Sirius Black schrieb:

    Eine Fehlermeldung ausgibt oder ligt genau das am Access Violation, hat dan jedes Array of char was ich statisch (oder dynamisch auch?)erzeuge noch 1 unbesetztes Element hintendran?

    Da sind wir wieder am selben Punkt. Die Schweinefüsschen (") hängen an den String automatisch ein Terminierungszeichen, das sind dann insg. wieder drei Zeichen, obwohl du nur für zwei reserviert hast. char [2] beutet, du reservierst nur für Element 0 und Element 1; (macht 2 Elemente).

    Und Accessviolations treten zur Laufzeit ein, sind also vom Compiler nicht vorauszusehen (deshalb auch so gefährlich).

    Sirius Black schrieb:

    Ach wo schon Cracks dabei sind, wie beugt man Programmabstürze bei zu langen Strings vor?

    Da gibt's viele Möglichkeiten. Wenn du schon mit C arbeitest, dann bediene dich an den "sicheren" Speicherverwaltungs / Stringfunktionen aus der Standardbibliothek. Weis nicht, ob es in C Exceptionhandling gibt, ansonsten solltest du das auch hernehmen. Die beste Lösung wär aber nach wie vor C++.



  • Don06 schrieb:

    Solange man die Arrays per Referenz übergibt bleiben die Typinformation (weitesgehend) erhalten.

    dann mach das doch mal mit 'ner richtigen funktion, nicht mit diesem template-trick.
    🙂



  • @Apeman:
    Für mich sind Template-Funktionen richtige Funktionen, nur das sie statische Parameter haben. Ich könnte zB einen std::vector ohne Templates auch nur schwer nachprogrammieren (nur mit blödem gecaste, aber das will man ja nicht).
    Du kannst Arrays mit statischer Größe auch ohne Templates per Referenz übergeben, musst dann aber die Größe immer mirangeben und diese Arbeit nehmen einem die Templates ja ab, also warum nicht. Das würde auch den typischen Anfängerfehlern vorbeugen, die sizeof() auf eine übergegebenes Array anwenden. sizeof() funktioniert nämlich richtig für Array-Referenzen.

    Gruß
    Don06


Anmelden zum Antworten