strtok



  • Bengo schrieb:

    Also kann man die Einzelnen toks nicht in anderen Strings fixieren.

    Die einzelnen Token sind bereits eigene Strings. Kopieren kannst du sie, wie schon erwähnt wurde, mit strcpy(). Vielleicht ist dir nicht klar, was ein C-String eigentlich ist. Oder uns ist nicht klar, was du eigentlich vorhast.



  • Man kann (zum wiederholten Mal: strcpy()), allerdings nicht in eine char-Variable, sondern bestenfalls in ein (ausreichend großes) char-Array. Ob es notwendig ist, ist die andere Frage.
    Kannst du eventuell mal erklären, was du effektiv vorhast? Wenn wir verstehen, was du mit der gesamten Konstruktion erreichen willst, können wir dir zielgerichteter helfen.



  • Wäre auch ratsam, mal zu erklären, seit wann du nun c programmierst und ob Quereinstieg oder nicht. Dann kann man seine Erklärungen etwas anpassen/verfeinern.

    Was meinst du mit fixieren? Einen Zeiger auf jedes Vorkommen oder eine Kopie jedes Vorkommens? Es geht da natürlich beides, aber versuch dich mal besser auszudrücken. Am besten mit ieiner Aufgabenstellung oder Beispiel 😉



  • Du hast einen C-String, also einen nullterminierten Array von ASCII-Zeichen. In diesem String kommt als Trennzeichen ein TAB (ASCII = 9) vor, nach dem du den String zerlegen willst. Ist das richtig verstanden? Siehe dir einfach die Standardfunktionen von string.h an oder drösel den String mit oder ohne Zeiger selbst auf.



  • Konkret möchte ich einen String, der aus Zahlen und Tabzeichen besteht die Zahlen herausfiltern.

    etwa so:

    char String[100]={"1 Tab 2 Tab 3 Tab 4"};
    char zahleins[100];
    char zahlzwei[100];
    und so weiter
    char* Zahlen=strtok(String, 'Tab');
    strcpy(zahleins, Zahlen);
    char* Zahlen=strtok(NULL, 'tab');
    strcpy(zahlzwei, Zahlen);



  • Das dürfte so schon fast funktionieren.
    - Die {} kannst du weglassen.
    - Tab werden durch '\t' dargestellt.
    - beim zweiten strtok die deklaration entfernen.

    BTW:
    Wenn du die Zahlen herausfiltern willst, dann hilft dir evt. auch strtol. Die Funktion gibt dir allerdings ein long zurück(interessant auch der 2. Parameter).

    Bei einem String von 100 Zeichen hast du dann aber auch maximal 50 verschiedene Werte zu speichern. Demnach bräuchtest du dann auch soviele Variablen, die du der übersichthalber in ein Array einquartieren könntest.(wenn es nicht um performance geht, kannst du auch dynamisch speicher vergeben)



  • Für deinen Fall brauchst du den String nicht extra zu zerstören nur um durch Whitespaces getrennte int-Werte auszuwerten, das geht auch mit sscanf, der String bleibt erhalten und int-Werte hast du auch sofort, ohne Teilstrings noch extra umwandeln zu müssen:

    char *s="\t1\t22\t333\t4444\t5555\t";
      int n=0,x;
      while( s+=n,1==sscanf(s,"%d%n",&x,&n) )
        printf("%d\n",x);
    


  • Habe jetzt etwas umgeschrieben, aber der Compiler gibt die Fehlermeldung, dass der Pointer ohne cast sei

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char *argv[])
    {
    char String[100]={"1\t2"};
    char zahleins[100];
    char zahlzwei[100];
    char* Zahlen=strtok(String, '\t');
    strcpy(zahleins, Zahlen);
    Zahlen=strtok(NULL, '\t');
    strcpy(zahlzwei, Zahlen); 
    
    pritnf("s", zahleins);
    pritnf("s", zahlzwei);
    system("PAUSE");
    return 0;
    }
    


  • Nimm Wutz Methodik 😉

    pritnf("s", zahleins);
    

    Ist nicht korrekt. Zum einen heißts printf(). Zum anderen ist der format specifier mti einem % anzuführen, also "%s".



  • Bei gibt der Compiler bei der while schleife eine Fehlermeldung: incompatible types in assignment



  • Es ist immer gut zu wissen wo der Fehler auftritt.
    Das gute beim Programmieren ist, dass der Compiler sogar sagt, wo er den Fehler findet.

    Es wäre also gut, dass du uns das auch mitteilst. Das macht das Ganze viel einfacher.

    Dann schau dir mal die Paramterliste von strtok() an.
    Das erwartet zwei char*. Du übergibst an zweiter Stelle aber ein char.

    strtok(String, "\t); \\ achte auf die ""
    

    Und nimm ruhig scanf.



  • Ich meinte die while Schleife von Wutz



  • Bengo schrieb:

    Ich meinte die while Schleife von Wutz

    Und ich bezog mich auf dein Post von 19:33:25 22.10.2011. Denn in 11 Sekunden bekomme ich so eine Antwort auch nicht hin 😃

    Hast du copy & paste gemacht oder abgeschrieben?



  • Hmm, das mit dem ',' in der while ist generell gültig? Hatte ich nur noch nie gesehen.

    Achja, wenn der String nicht "zerstört" werden darf, dann solltest du Wutzs Beispiel auch noch so anpassen, dass dein String nicht verloren geht 😉



  • Der String kann verloren gehen, die einzelnen Zahlen sollten dann ihre eigenen Variablen bekommen.



  • DaRe schrieb:

    Hmm, das mit dem ',' in der while ist generell gültig? Hatte ich nur noch nie gesehen.

    Das ist der Kommaoperator.
    Kommt meist bei for-Schleifen vor, wenn man mit zwei Variablen arbeitet.



  • Apropos for-Schleifen: Diese while-Schleife ließe sich eleganter als for-Schleife schreiben:

    for(s = data; 1 == sscanf(s, "%d%n", &x, &n); s += n) {
      printf("%d\n", x);
    }
    

    Wobei ich mir überlegen würde, den sscanf-Overhead einzusparen und gleich auf strtol aufzusetzen:

    char const *current;
      char *next; /* Nicht, dass da nachher jemand reinschreibt; das ist nur wegen strtols Signatur nicht const */
      long x;
    
      for(current = data;
          x = strtol(current, &next, 10), current != next;
          current = next) {
        printf("%ld\n", x);
      }
    

    Da wär dann auch der Komma-Operator wieder dabei.



  • Gibt es denn nicht eine einfache variante?



  • Was ist denn einfacher für dich?
    - Was du verstehst?
    - Wenig Befehle?

    Wenn das immer die gleich Anzahl Zahlen ist:

    char *s="\t1\t22\t333\t4444\t5555\t"; 
    int zahl1, zahl2, zahl3, zahl4, zahl5;
    
    sscanf(s," %d %d %d %d %d", &zahl1, &zahl2, &zahl3, &zahl4, &zahl5);
    


  • Danke hat mir sehr geholfen.


Anmelden zum Antworten