- Labornetzteil AliExpress         
Seite 1 von 6 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 52

Thema: Char - Array und Pointer

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645

    Char - Array und Pointer

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,

    hier mal in Beispiel, dass ich gerne erklärt hätte:

    Code:
    char* myArray[128];
    
    //Funktion
    void xxx(char** ar){
      ar[0] = irgendeineZeichenkette;
    }
    
    //Funktionsaufruf
    xxx(myArray);
    Es geht jetzt nicht darum, warum ich das jetzt genau so geschrieben habe (das ist, weil es anders nicht möglich war).
    Es ist so.
    Der Code funktioniert am Ende.

    Ich möchte eigentlich ein Array anlegen, dass Platz für 128 Zeichenketten bietet.
    Klar ist mir, dass der Compiler nicht wissen kann, wie lang eine Zeichenkette sein kann, wenn er auf dieses Konstrukt trifft: myArray[128]
    Aber was passiert jetzt genau, bei char* myArray[128]? Bekomme ich hier ein Array mit reserviertem Speicherplatz für 128 Pointer (char*)?

    Dann muss ich das einer Funktion übergeben, in der noch etwas mehr passiert, als das, was jetzt hier steht - eine Funktion, die ein char* erwartet: strtok()
    Aus diesem Grund komme ich über die ausgeworfenen Fehlermeldungen zu dem char** . Das funktioniert zwar, aber bei char** weiß ich nicht mehr, was es bedeuten soll. Soll das ein Zeiger auf einen Zeiger sein?

    Ich hoffe, dass mir das irgendeiner richtig erklären kann, zurzeit blicke ich da noch nicht durch!



    MfG


    PS: Falls das Thema hier deplaziert ist, evtl. bitte verschieben nach: Forum -> Microcontroller -> Software, Algorithmen und KI

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    Aber was passiert jetzt genau, bei char* myArray[128]? Bekomme ich hier ein Array mit reserviertem Speicherplatz für 128 Pointer (char*)?
    Soll das ein Zeiger auf einen Zeiger sein?
    korrekt

    Du kannst Pointer auf Pointer auf Pointer auf Pointer ... biegen wie du lustig bist

    Beim dereferenzierne musst du dann nur auf die Anzahl der Sternchen achten damit du am Ende auch beim Ergebnis ankommst und nicht versuchst das Array von Pointern als String auszugeben.

    Wenn du aber eine Zeichenkette einfügen möchtest, musst du diese irgendwo anders definieren und dann den Pointer darauf in dem Array speichern oder per malloc erzeugen und später wieder freigeben (oder gleich auto:ointer nehmen, aber ich wollte hier nciht nach C++ abdriften)
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Nach einiger Recherche gestern Abend noch, soll das so sein, wie Du gesagt hast. Allerdings verstehe ich es noch nicht.
    Normal habe ich einen Speicherbereich, mit einem Bezeichner dazu, um den anzusprechen.
    Das würde ich evtl. so machen: char myArray[128]
    Aber ich muss char* .. schreiben ?

    Ich muss mein dickes C++-Buch raus holen, steht ja im Schrank. Hatte schon ganz vergessen, über die Jahre.
    Vielleicht finde ich dort auch was über strtok().

    Beim dereferenzierne musst du dann nur auf die Anzahl der Sternchen achten


    Das funktioniert dann merkwürdiger Weise mit:
    Serial.println(myArray[x]);





    MfG

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    Das funktioniert dann merkwürdiger Weise mit: Serial.println(myArray[x]);
    Das ist ja auch richtig, weil println() einen char* erwartet und du das x-te element vom typ char* übergibst!

    Ein string ist ein Array aus Pointern und der Bezeichner eines Array, also "char Bezeichner[5]" ist selbst ebenfalls ein Pointer, also "Bezeichner" ist vom Typ char*, weil du die Array notation mit "[ ]" angefügt hast.

    Ich bin noch nicht ganz durchgestiegen wo genau die Frage liegt, vielleicht könntest du mir die Frage noch ein wenig einengen oder ich brauch noch ne Tasse Kaffe (Scheiß Zeitumstellung, bringt meine innere Uhr ausm Takt)
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Das Problem liegt darin, dass ich noch nicht weiß, welche Funktionen/Methoden was für Parameter erwarten oder was sie zurückgeben.

    eigentlich ist es einfach, ich wollte so was, wie das:

    Code:
    myString = "Hallo, dass bin ich, weil ich hier bin.";
    myArray = myString.split(',');
    
    Ausgabe = "";
    
    for(i = 0; i< myArray.length(); i++) Ausgabe+=myArray[i]+'\n';
    
    alert(Ausgabe);
    Mehr wollte ich nicht. Bloß dass ich es jetzt nicht mit JavaScript, sondern mit C zu tun habe.
    Aber wenn ich das in C machen will, muss ich mich da reinarbeiten, nutzt nichts.

    Ich fand dann nicht split() sondern nur strtok().
    strtok() gibt offenbar einen Zeiger auf eine Zeichenkette zurück, was man bei C wissen muss, weil man sonst damit nicht weiter arbeiten kann. Weil in C überall die Datentypen anzugeben und ob das Zeiger, Adressen oder was anderes sind. Das kann ich aber nur, wenn ich eben genau weiß, welche Funktion was genau zurückgibt und erwartet.

    Sinn und Zweck der Übung ist es, von einer langwierig, für Einsteiger eher komplizierten und zeitraubenden Programmierung mit der Arduino-IDE, auf eine einfache Lösung zu kommen, wo man problem- und lösungsorientiert arbeiten kann und sich nicht überwiegend mit der Parameterübergabe und Fehlermeldungen des Compilers beschäftigen muss.




    MfG
    Geändert von Moppi (28.10.2019 um 08:12 Uhr)

  6. #6
    HaWe
    Gast
    for(i = 0; i< myArray.length(); i++) Ausgabe+=myArray[i]+'\n';
    das geht allerdings nicht in C, sondern nur in C++

    eine Übersicht über cstring Funktionen (ANSI/ISO C) findest du hier:
    http://www.cplusplus.com/reference/cstring/

    entspr. Funktion einfach anklicken, dann kommt eine Beschreibung mit code example, z.B:
    http://www.cplusplus.com/reference/cstring/strtok/

    - - - Aktualisiert - - -

    falls du ein paar cstring Funktionen suchst, die dort nicht enthalten sind, findest du hier vlt ein paar passende:

    Code:
    // Library: stringEx.h
    // extended C-string manipulation
    //
    // (C) dsyleixa 2015-2019
    // freie Verwendung für private Zwecke
    // für kommerzielle Zwecke nur nach Genehmigung durch den Autor.
    // Programming language: Arduino Sketch C/C++ (IDE 1.6.1 - 1.6.3)
    // protected under the friendly Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
    // http://creativecommons.org/licenses/by-nc-sa/3.0/   //   
    
    
    
    
    #ifndef  STRINGEX_H
    #define STRINGEX_H
    
    
    //------------------------------------------------------------
    
    char * sprintDouble();
    char * strinsert();
    char * strdelnpos();
    char * strpatch();
    char * substr();
    int16_t  strchpos();
    int16_t  strstrpos();
    char * stradd();
    char * cstringarg();
    
    
    
    //----------------------------------------------------------------------------
    // cstring functions
    //----------------------------------------------------------------------------
    
    char * sprintDouble(char* s, double val, int width, int prec, bool sign)  {   
       char sbuf[20] ="\0";
       strcpy(s, "\0");
       dtostrf(val, width, prec, s);
    
       if(sign && val>0) {
         for (int i=width-1; i>=0; i--) {
           if(s[i]==' ') {s[i]='+'; break;}
         }
       }
       return s;
    }
    
    
    
    //------------------------------------------------------------
    
    char * strdelnpos( char * source, int16_t  pos, int16_t  sublen ) {  // delete a substr in string at pos
       int   srclen;
       char  * sret = source;
    
       srclen = strlen(source);
    
       if( pos > srclen ) return sret;
       if( sublen > srclen-pos ) sublen = srclen-pos;
       memmove( source+pos, source+pos+sublen, srclen+sublen);
       source[srclen-sublen]= '\0';
       return sret;   
    }   
     
    
    
    //------------------------------------------------------------
    
    char * strpatch( char * source, char * sub, int16_t  pos )  {  // patch string by substr at pos
       int16_t srclen, sublen;
       char  * sret = source;
       
       srclen = strlen(source);
       sublen = strlen(sub);
       
       if( pos+sublen > srclen) return sret;   // size/position error
       memcpy(source+pos, sub, sublen);    
    
       return sret;     
    }
    
    
    
    //------------------------------------------------------------
    
    char  * substr  ( char * source, char * sub, int16_t  pos, int16_t len ) { // get substr of source at pos by length 
       char   *sret = sub;
    
       if ( (pos+len) >  strlen(source) ) len = strlen(source)-pos;  // cut away if too long
       sub = strncpy(sub, source+pos, len);
       sub[len] = '\0';
      
       return sret;  
    }
    
    
    
    
    //------------------------------------------------------------
    
    int16_t strchpos( char * str, char ch ) {       // find 1st occurence of char ch in string str
       int16_t  len, i=-1;
       
       len=strlen(str);
       if(len==0) return i;
       for(i=0; i<len; ++i) {
         if(str[i]==ch) break;   
       }   
       return i;
    }   
    
    
    
    
    //------------------------------------------------------------
    
    char * stradd(char * s, int n, ...)  // "adds strings" s=sumstring , n=number_in_list, ... = var string list
    {
        va_list vlst;    
        int i;
        
        char * bufptr;
        char * retptr = s;
        
        va_start(vlst, n);
        for (i=1; i<=n; ++i)   {
           bufptr = va_arg(vlst, char *);
           strcat(s, bufptr);
        }
        va_end(vlst);	
        return retptr;    
    }
    
    
    
    //------------------------------------------------------------
    
    int16_t  strstrpos(char * haystack,  char * needle)   // find 1st occurance of substr in str
    {
       char *p = strstr(haystack, needle);
       if (p) return p - haystack;
       return -1;   // Not found = -1.
    }
    
    
    
    //-------------------------------------------------------
    
    const int  MAXLEN = 1024;
    const int  TOKLEN = 64;
    
    //-------------------------------------------------------
    
    char * cstringarg( char* haystack, char* vname, char* sarg ) {  // search for &vname=sarg or ?vname=sarg, returns sarg  
       int i=0, pos=-1;
       unsigned char  ch=0xff;
       const char*  kini = "&";       // start of varname: '&'
       const char*  kin2 = "?";       // start of varname: '?'
       const char*  kequ = "=";       // end of varname, start of argument: '='
       char  needle[TOKLEN] = "";     // complete pattern:  &varname=abc1234
    
       strcpy(sarg,"");
       strcpy(needle, kini);
       strcat(needle, vname);
       strcat(needle, kequ);
       pos = strstrpos(haystack, needle); 
       if(pos==-1) {
          needle[0]=kin2[0];
          pos = strstrpos(haystack, needle);
          if(pos==-1) return sarg;
       }
       pos=pos+strlen(vname)+2; // start of value = kini+vname+kequ   
       while( (ch!='&')&&(ch!='\0') ) {
          ch=haystack[pos+i];    
          if( (ch=='&')||(ch==';')||(ch=='\0') ||(ch=='\n') ||(ch=='\r')
            ||(i+pos>=strlen(haystack))||(i>TOKLEN-1) ) {
               sarg[i]='\0';
               return sarg;
          }       
          if( (ch!='&') ) {
              sarg[i]=ch;          
              i++;       
          }      
       } 
       return sarg;
    }
    
    
    //------------------------------------------------------------
    #endif
    //------------------------------------------------------------
    //------------------------------------------------------------
    Geändert von HaWe (28.10.2019 um 12:09 Uhr)

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    Ausgabe+=myArray[i]+'\n'
    DAS geht so leider nicht, in reinem C gibt es keine dynamischen Strings, du müsstest also entweder hybrid mit ein bisschen C++ und String als Klasse arbeiten oder deine "Ausgabe" als Array bestimmter größe Vorinitialisieren damit genug Platz reserviert ist um alle Zeichen aufnehmen zu können.

    Es gibt Funktionen wie strncat und co. aber ein simples Ausgabe+=irgendwas+"noch was statisches"; dürfte dir dein compiler eigentlich schon um die Ohren hauen.

    http://www.cplusplus.com/reference/cstring/strtok/

    strtok sucht halt nach dem übergebenen token und gibt dir einen Pointer innerhalb des char arrays den du dann mittels memcpy oder strcpy (oder strncpy) in ein anderes array kopieren kannst (gibt aber auch diverse andere string methoden in c)

    Aber
    Das kann ich aber nur, wenn ich eben genau weiß, welche Funktion was genau zurückgibt und erwartet.
    Das ist die Kunsst zu googeln oder man holt sich ein gutes Buch mit inhaltsverzeichnis wenn man offline arbeiten will. Ich kann dir auch nciht aus dem FF sagen welche Funktion wie zu bedienen ist und Methoden die ich vor 3 Jahren verwendet habe muss ich auch heute immer noch nachschlagen weil man sich nciht alles merken kann. Es ist aber immer gut in Bild im Kopf zu haben wie der Speicher verawltet wird statt sich nur auf die Verwendung der EMthoden zu konzentrieren!

    Ich schreib hier mal nur meine persönliche Sichtweise auf nach der ich arbeite bzw. wie ich es mir vorstelle wenn ich von einem single Thread Prozess ausgehe oder wie es halt im µController tickt, solange ich keine Interrupts einsetze!

    JEDER Variable die ich anlege, wird beim compilieren vom Linker im RAM eine feste Position vorgegeben (Optimierung lasse ich mal außen vor).
    Diese Variablen haben dann eine feste Größe und im Fall von Arrays sind das dann halt N viele Variablen hintereinander.

    Wenn ich dynamisch arbeiten will muss sich jemand (im Fall von C ich selbst) darum kümmern diesen Platz zu reservieren und auch wieder freizugeben!

    Wenn ich aber nciht mit malloc, calloc und free arbeiten möchte (ist halt absolut pain in the butt) muss ich halt entsprechend große Puffer Arrays vorhalten in denen ich dann arbeite und mir meine Ergebnisse dann irgendwo hin kopieren.

    Wenn Interrupts oder Multithreading dazu kommen wirds nochmal spannender, dann musst du sicherstellen dass eine Schleife die in einem Arrray etwas macht nicht z.B. durch einen Interrupt unterbrochen wird, in welchem neue DAten ins Array geschrieben werden.

    Wenn ich jetzt mal Java als Referenz nehme, wenn ich eine Liste von Bytes habe (als Ersatz für das char Array) und über diese mit einem Iterator (intelligenter Pointer der sich selbst weiterschieben kann) zugreife, dann aber ein anderer Prozess diese Liste manipuliert, schmiert mir der nächste Zugriff auf den Iterator mit der "Concurrent Modification" Exception ab, also Konkurrierender Zugriffsfehler.

    In Java kann man dann das Modell der Liste ändern und eine Threadsafe Implementation nehmen ... im Einfachsten Fall wird eine Kopie deiner Liste erzeugt, über die der Iterator läuft, während die eigentlichen Daten verändert werden können. du kannst dann nur nicht erwarten, dass der Iterator sich ebenfalls verändert.

    in C++ nimmt man die String Klasse, weil diese bereits dynamischen Speicher einsetzt (Aber immernoch das Problem mit "new" und "delete" hat statt malloc und free)

    Oder man kann die auto:: pointer (das leerzeichen ist nur weil er sonst einen smiley draus macht) library benutzen (bim Namen bin ich mir nicht sicher) weil dir dort viel Arbeit abgenommen wird.

    Strings in C sind gruselig finde ich persönlich.
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  8. #8
    HaWe
    Gast
    ....wobei hinzukommt, dass (groß geschrieben)
    String
    eine spezielle Arduino-Klasse ist, die C++ "benutzt",

    hingegen (klein geschrieben)
    string
    eine allgemeine C++ std Klasse ist, genau: std::string

    Vergeicht man String mit string, fallen einem manche Gemeinsamkeiten, aber auch erhebliche Unterschiede auf, und std::string ist deutlich mächtiger als String und braucht deutlich mehr Speicher.


    zur Unterscheidung sollte man die ISO C char arrays
    char * mystrp;
    char mystra[100]:
    als cstrings bezeichnen, um Verwechslungen zu vermeiden

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Ja, danke für den Link, HaWe!!

    Dann werde ich dort mal öfter reinschauen.

    Allerdings, was strtok() tut, habe ich dann rel. schnell - auch wegen der Fehlermeldungen - herausgefunden. Jetzt, wo ich es nachlesen kann, deckt sich das mit meiner Vorstellung über strtok().

    @Ceos
    Das mit google ist so eine Sache. Dort finde ich schon längere Zeit nichts wirklich Brauchbares. Mit Pech ist unter den ersten Links Werbung (dh. die sind wenig oder gar nicht relevant) und unter den anderen Ergebnissen werden die auch nicht nach meiner Suche richtig gewichtet, jedenfalls nicht so, wie ich das erwarten würde. Wenn ich zum Beispiel "(String)" eingeben (auch gerne in Gänsefüßchen eingefasst), erhalte ich eben nicht überwiegend Erklärungen zu "String" oder "(String)" oder String und Compilern wie C/C++, sondern vornehmlich irgendeinen Unfug, der daraus entsteht, dass man in meiner Suche nach Wörtern sucht, mittels derer sich Geld verdienen lässt, was dazu führt, dass ich Kaufangebote über Strings bekomme. Probier es mal aus! Es ist grausam geworden mit google, finde ich!






    MfG

  10. #10
    HaWe
    Gast
    das mit anklicken von strtok war ntl nur ein Beispiel, das tolle an cplusplus.com sind die code-Beispiele zu allen einzelnen Funktionen und die Übersicht über ähnliche, zusätzliche und weiterführende Funktionen.

    google macht es doppelt schwierig, weil es auch nicht Groß/Kleinschreibung unterscheidet, und String ist eben etwas anderes als string.

Seite 1 von 6 123 ... LetzteLetzte

Ähnliche Themen

  1. Pointer auf Struct von Byte-Array
    Von Bumbum im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 31.05.2013, 16:01
  2. Char mit array verbinden ?
    Von AsuroPhilip im Forum Software, Algorithmen und KI
    Antworten: 22
    Letzter Beitrag: 08.09.2011, 13:37
  3. gelöst : Frage zu C und 2 Dim char Array
    Von jar im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 29.05.2007, 16:53
  4. zweidemensionales char-array
    Von p_mork im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 15.03.2007, 16:54
  5. Cstring einem char array zuweisen
    Von ceekay im Forum Software, Algorithmen und KI
    Antworten: 8
    Letzter Beitrag: 17.04.2006, 10:20

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests