schleife rückwärts, von xx bis auf 0 runterzählen.



  • Gibts ja nicht, ich hatte es zwischenzeitlich auch mal mit i-- stehen und weils nicht ging dachte ich i-1 wäre besser.
    Also ich hab jetzt nur statt i-1 i-- geschrieben und das else konnte ich komplett weglassen(kann aber auch bleiben, geht auch).

    int i=200;
    while (i >=0) 
      	{
    	if (text[i]=='.')
    	{
    	printf("ein punkt sitzt auf array index nr %d\n", i);
    	i--;
    	}
    	i--;
    
       }
    

    Und schon läufts 🙄

    Aber mit dem Befehl str(n)cpy in string.h muss ich mich erstmal auseinander setzen.. 😮 Da weiß ich garnichs mit anzufangen, steht das n für die Indexnummer? Ich werd mal recherchieren, Danke auf jeden fall schonmal! 👍



  • Du hast ein i-- zuviel.

    Zudem musst du an deinem Einrückungsstil arbeiten: https://de.wikipedia.org/wiki/Einrückungsstil

    Ein C-String ist am Ende durch ein '\0' gekennzeichnet.
    Da man das Ende erst findet, wenn man von vorne anfängt zu suchen, ist die rückwärtssuche eher schlecht.

    In deinem Beispiel, wo du gleich den C-String initialiserst, wird der ungenutzte Rest mit Nullen aufgefüllt.
    Das ist bei dem strcpy schon anders. Da kann es sein, dass du auf Müll zugreifst.

    char text[256] = "kuchen.txtf3f38fh38.c.trr"; // text ist jetzt ein Zeiger
    int i=0;
    
    while (text != '\0')  // bis ein '\0' gefunden wird
    { if (text[i]=='.')
      { 
        printf("ein punkt sitzt auf array index nr %d\n", i);
      }
      i++;
    }
    

    Wenn du mit argv arbeiten möchtest, bietet sich an, aus [i]text einen char -Zeiger zu machen.

    Das n in strncpy soll für eine Anzahl (maximale Länge) stehen. Allerdings wird die '\0' nur mitkopiert, wenn n nicht erreicht wird.
    Im Zweifel hast du einen nicht terminierten String.



  • DirkB schrieb:

    Ein C-String ist am Ende durch ein '\0' gekennzeichnet.
    Da man das Ende erst findet, wenn man von vorne anfängt zu suchen, ist die rückwärtssuche eher schlecht.

    In deinem Beispiel, wo du gleich den C-String initialiserst, wird der ungenutzte Rest mit Nullen aufgefüllt.
    Das ist bei dem strcpy schon anders. Da kann es sein, dass du auf Müll zugreifst.

    Guter Punkt. 👍 Wenn es denn (aus gegeben Gründen) unbedingt rückwärts sein soll vorher die Länge des Strings ermitteln (strlen()) und an der richtigen Position anfangen zu suchen.

    Wenn du mit argv arbeiten möchtest, bietet sich an, aus text einen char -Zeiger zu machen.

    Ich lese da [i]text , das ist offensichtlich ein Bug (i ist BB-Code für kursiv). Es muss einfach text heissen.
    ( [i]text ist gültiges C aber ungewöhnlich...)

    (@TO)
    Wenn du argv[1] nicht verändern möchtest kannst du direkt damit arbeiten oder nur einen Pointer darauf nutzen wie vorgeschlagen:
    char *text=&argv[1];
    oder: char *text=(argv+1);
    ist beides vom Ergebnis gleich.



  • döööööööner schrieb:

    ( [i ]text ist gültiges C aber ungewöhnlich...)

    Sorry, da sollte text stehen. (kursiv)

    döööööööner schrieb:

    char *text=&argv[1];
    oder: char *text=(argv+1);
    ist beides vom Ergebnis gleich.

    aber falsch, da argv vom Typ char** ist

    char *text = argv[1];   // kein &
    oder: 
    char *text = *(argv+1); // oder dereferenzieren
    


  • Du hast ein i-- zuviel.

    Oh ja, jetzt seh ichs! Vielen Dank! Damit wurde ja nur jeder zweite index überprüft 😮

    Mir gings in diese Fall erstmal nur um den Punkt, und zwar um genau zu sein den allerletzten. Weil der Punkt nämlich über die Dateiendung entscheidet, und die ist für mich interessant.

    Ich muss ein Programm schreiben welches mir die Dateiendungen von Dateien ändert.
    mit dem Programmaufruf:
    ./programm *.txt *.ini
    Sollen alle txt Dateien in ini Dateien umbenannt werden.
    Dafür war mein Ansatz jetzt dass das Programm erstmal den hintersten Punkt finden muss, da ein Dateiname ja auch "dokumentversion1.3.4.5.docx" heißen kann. Da wäre es fatal wenn man einen anderen Punkt als den letzten nimmt.

    Dass ich jetzt unbedingt von hinten suchen wollte klang mir zuerst als sinnvoll, als nur mit vorwärtszählen funktionierte wollte ich einfach wissen wieso es nicht von hinten ging. ("Ehrgeiz 😃 Kann doch nicht wahr sein, wieso..."

    Die Geschichte mit dem Argument kann ich leider gerade nicht weiter verfolgen, evtl hab ich heute Abend nochmal Zeit dafür. Wollt euch nur schonmal kurz den weiteren Hintergrund erläutern.



  • DirkB schrieb:

    aber falsch, da argv vom Typ char** ist

    Argh, natürlich! Entschuldigung.



  • Du kannst beim Suchen vom Ende dir ja die Position vom letzten '.' merken.

    char text[256] = "kuchen.txtf3f38fh38.c.trr"; // text ist jetzt ein Zeiger
    int i, pos;
    
    for (i=0,pos=-1; text[i] != '\0'; i++)  // bis ein '\0' gefunden wird
    { if (text[i]=='.')
      {
    //    printf("ein punkt sitzt auf array index nr %d\n", i);
        pos = i;
      }
    }
    Entweder ist pos -1, dann gab es keinen '.' oder es ist der Index vom letzten '.'
    

    Es ist in Ordnung wenn du das erstmal selber rausfinden willst.
    Die Erfinder von C hatten auch das Problem, deshalb haben sie eine entsprechende Funktion in die Standard Library eingebaut. Die Deklaration ist in string.h http://www.cplusplus.com/reference/cstring/

    Da die Aufgabenstellung mit dem Umbennenen etwas komplexer ist, solltest du auf fertige Funktionen zurück greifen.



  • So ich hab mich nochmal dran gesetzt.
    Ich bin erstmal dem Tipp nachgegangen "test" als Zeiger zu deklarieren, mit Zeigern hab ich zwar auch meine Probleme aber von den anderen Befehlen hab ich noch nie was gehört, deswegen :p

    Mein Programm sieht jetzt so aus:

    #include <stdio.h>
    
    int main (int argc, char **argv)
    {
      char *text=argv[1];
      int n;
    	for (n=0; text[n]!='\0'; n++)
    	{
    	  printf("index nr.%d: %c\n", n, text[n]);
    	}
    
      printf("die variable im ganzen als string: %s\n", text);
    
      int i=200;
      while (i >=0)
    	{	if (text[i]=='.')
    		{
    	       	  printf("ein punkt sitzt auf array Index nr %d\n", i);
    		}
    		i--;
    	}
    return 0;
    }
    

    Hab mir die einzelnen Buchstaben zur Sicherheit noch anzeigen lassen.

    Die Ausgabe sieht so aus:

    alex@debian:~/Schreibtisch/cprog$ ./arraym test.v2.txt
    index nr.0: t
    index nr.1: e
    index nr.2: s
    index nr.3: t
    index nr.4: .
    index nr.5: v
    index nr.6: 2
    index nr.7: .
    index nr.8: t
    index nr.9: x
    index nr.10: t
    die variable im ganzen als string: test.v2.txt
    ein punkt sitzt auf array Index nr 153
    ein punkt sitzt auf array Index nr 7
    ein punkt sitzt auf array Index nr 4
    alex@debian:~/Schreibtisch/cprog$

    Schon fast gut 😃
    Da gibts wohl ein Problem dass der Speicher noch von was anderem belegt ist... Weil an Stelle 153 ist kein Punkt... Und je nachdem wie lang ich das Wort mache wo jetzt "test.v2.txt" steht ändert sich die 153...

    Ich frage mich jetzt auch wieviele Indexe es wohl in meiner *text Variable gibt 😕 Vorher hab ich die Anzahl festgelegt mit [256]. Lasse ich die 256 stehen kommt aber ein Compilierungsfehler...

    Soweit so gut, nochmal alles eben überflogen und durchgelesen. Jetzt seh ich erst dass es diese und diverse ähnliche Funktionen schon "fertig" gibt.. 😮 Die Aussage habe ich vorher nicht so ganz kapiert..
    Ok, auch gut 😃 Muss ich mich mit befassen, das könnte die Sache evtl einfacher machen. (wirds vermutlich, nur momentan sehe ich das noch nicht weil ich die Funktionen nicht kenne 🙄 )

    Kann mir aber noch jemand sagen wie meine selbstgebautes Zeichenfind-Programm richtig funktioniert ohne die Pseudo-Nr 153 ?



  • vorhin war das Array groß genug. Jetzt hast du aber einen Zeiger auf argv[1]. Der Speicher dort ist kleiner als 200 Zeichen und er gehört dir (bzw. dem Programm) nicht.

    Direkt im Anschluß liegen andere Variablen. Daher ist es eine ganz blöde Idee da rumzupfuschen.

    Um 14:53:34 habe ich eine funktionierende Lösung gepostet.
    strrchr arbeitet ähnlich, allerdings mit Zeigern (die wollte ich dir ersparen)

    Da du aber weder die Grundlagen von C-Strings noch strcpy kennst, solltest du erstmal in deinem Buch/Tutorial weitermachen.

    Gerade bei Arrays und Strings ist C anders als viele Programmiersprachen.



  • Indem du die Rückwärtssuche am Stringende von text startest und nicht auf Zeichen im Speicher zugreifst, die hinter dem Ende von text liegen.



  • Du hast doch in deiner for-Schleife mit n gezählt wie viele Buchstaben in dem String sind, mach das i weg und setze das n in die while Schleife.

    char *text=argv[1];
    

    Du musst zuerst überprüfen ob überhaupt ein Kommandozeilenargument übergeben wurde.



  • @ Wutz, Danke das klingt einleuchtend, die 200 hab ich vorher nur gewählt da sie unter 256 liegt!

    @DirkB
    Ich hab deine Lösung von 14:53 gesehen aber mich gewundert wie das geht:

    char text[256] = "kuchen.txtf3f38fh38.c.trr"; // text ist jetzt ein Zeiger
    

    Die Zeile ist unverändert aber ist jetzt ein Zeiger sein? Sorry hätte trotzdem deine Lösung weiter verfolgen sollen, hab nicht genau hingesehen was noch alles anders ist...

    @Bitmapper:
    Danke für den hinweis, ja ich sollte noch prüfen ob die Argumente überhaupt da sind, das hab ich jetzt erstmal weggelassen weil ich den Code übersichtlich halten wollte und ja erstmal es nur selber teste.
    Und der Tipp mit dem n statt i ist genial, bin ich vorher garnicht drauf gekommen aber auch durch den Hinweis von Wutz ists jetzt klar 🙂
    Hab mich eben echt erst gefragt woher ich denn wissen soll wieviele Zeichen es sind... hab se ja vorher schon gezählt 🙄

    So und ich hab eben schon die ganze Aktion mit der fertigen Funktion "strrchr" erledigen können 🙄 🕶
    Beispiel:

    #include <stdio.h>
    #include <string.h>
    
    int main (int argc, char **argv)
    {
      char *str = argv[1];
      char * pch;
      pch=strrchr(str,'.');
      printf ("Letztes Auftreten von '.' an Stelle %d \n",pch-str+1);
      return 0;
    }
    

    Klar, man müsste noch mit if überprüfen ob überhaupt ein Parameter da ist und wieviele usw.. aber nur das grundsätzliche Prinzip meine ich... 😉



  • Alfex schrieb:

    @DirkB
    Ich hab deine Lösung von 14:53 gesehen aber mich gewundert wie das geht:

    char text[256] = "kuchen.txtf3f38fh38.c.trr"; // text ist jetzt ein Zeiger
    

    Die Zeile ist unverändert aber ist jetzt ein Zeiger sein? Sorry hätte trotzdem deine Lösung weiter verfolgen sollen, hab nicht genau hingesehen was noch alles anders ist...

    Du hast recht text ist ein Array.
    Da sollte

    char *text = "kuchen.txtf3f38fh38.c.trr"; // text ist jetzt ein Zeiger
    

    stehen.
    Ich hatte da zuviel zurück editiert. 🙄
    Das Verhalten vom Programm ändert sich hier aber nicht.

    Und mit funktionierender Lösung meinte ich die for-Schleife. In pos steht das letzte vorkommen vom '.' und in i die Länge vom Text. In einem Durchlauf.
    Muss aber nicht schneller sein als strlen und strrchr nacheinander, da diese optimiert sind.

    Bei strrchr solltest du aber überprüfen, ob pch ungleich NULL ist, bevor du weiter machst.



  • Hab mir deine schleife von 14.53 nochmal angesehen, sieht doch ganz gut aus merke ich gerade 🙂

    Ja ich muss mir was einfallen lassen was geschehen soll wenn kein Punkt vorhanden ist. Muss halt eine Meldung kommen dass keine passende Datei gefunden wurde o.Ä.

    Da ist noch viel Arbeit vorhanden!

    Ich muss ja noch einlesen wie die neue Endung heißen soll, muss die alte Endung dann damit ersetzen usw usw...

    Außerdem soll der Standardbefehl ./programm alt.txt neu.txt auch noch funtkionieren. (also das was eig. der mv-shell-Befehl eh kann nachbauen)
    In dem Falle darf es nur 2 Parameter geben, für den Fall mit der Dateiendung aber beliebig viele da je nach Anzahl mehr oder weniger von der Linux shell übergeben werden...

    Aber ich bin alleine durch die string.h Bibliothek schon ein ganzes Stück weiter!

    Heute ist aber erstmal Feierabend, und mal sehen wies am Wochenende weiter geht 🙂

    Morgen steht erstmal eine "oldschool" LAN-Party auf dem Programm 😃 :p



  • string.h ist keine Bibliothek sondern eine Headerdatei.

    Darin sind lediglich die Funktionen zur Strinbehandlung der C Standard Library deklariert.
    Die Library wird immer mit zu deinem Programm gebunden und da sind fast alle Standard-Funktionen enthalten.
    Fast, denn die Funktionen aus math.h sind teilweise in einer eigenen Library.
    http://en.cppreference.com/w/c/header

    Oldschool ist, ein Buch (aus Papier) über C zu lesen.



  • Ok dann hab ich das falsch verstanden, hab das irgendwie als "Bibliothek" aufgefasst. Merke ich mir!

    Zu dem "oldschool"... muss ja nicht jeder mögen, dachte nur hier gibts eher Leute die sich auch für sowas begeistern können als bei anderen Foren die sich mit ganz anderen Dingen befassen...

    Aber Rechst haste wohl damit, bisher lese ich aber eher online Infos dazu bzw. Bücher als ebook 😉


Anmelden zum Antworten