schleife rückwärts, von xx bis auf 0 runterzählen.
-
Ich verzweile gerade an einer scheinbar einfachen Aufgabe.
Ich habe ein char erstellt und möchte das Wort was dadrin steht auf ein Zeichen, in meinem Fall ein Punkt, überprüfen.
Zuerst will ich mir nur alle Adresse wo Punkte stehen anzeigen lassen. (Die eigentlich Aufgabe steht noch in weiter ferne...)
Mit einer while schleife die aufwärts zählt klappt das auch.
Ich möchte die schleife aber von hinten beginngen lassen zu zählen und daran scheitere ich...
So gehts mit aufwärtszählen:
char text[256]="kuchen.txtf3f38fh38.c.trr"; int i=0; while (i <= 200) { if (text[i]=='.') { printf("ein punkt sitzt auf array adresse nr %d\n", i); i++; } else i++; }
Das Programm sagt mir an welchen stellen ein Punkt steht.
Ich wills andersherum:
char text[256]="kuchen.txtf3f38fh38.c.trr"; int i=200; while (i >= 0) { if (text[i]=='.') { printf("ein punkt sitzt auf array adresse nr %d\n", i); i-1; } else i-1; }
Geht nicht
Und weiß jemand wie ich ein argv in meine Text Variable kriege?
Wenn ichchar text[256]=argv[1];
versuche kommt beim Komplieren ein Fehler: Invalid initializer
Ich möchte einfach das Wort wo jetzt "kuchen.txtssdgf....." steht beim Programmaufruf übergeben, also zB Programmaufruf so:
./Programm kuchen.txt
-
falsch: i-1;
richtig: i=i-1;
oder: i--;Warnungen aktivieren, der Compiler dürfte bei der falschen Variante was zu meckern haben (statement without effect).
Ach und es geht einfacher:
char text[256]="kuchen.txtf3f38fh38.c.trr"; int i=0; while (i <= 200) { if (text[i]=='.') { printf("ein punkt sitzt auf array adresse nr %d\n", } i++; }
Auf die Formatierung achten, das erspart so manchen blöden Fehler.
Ganz kleinlich: Das was du anzeigst ist nicht die Adresse sondern der Index vom Punkt im Array. Adresse wäre &text[i] oder equivalent (text+i).Alfex schrieb:
Und weiß jemand wie ich ein argv in meine Text Variable kriege?
Wenn ichchar text[256]=argv[1];
versuche kommt beim Komplieren ein Fehler: Invalid initializer
str(n)cpy in string.h
-
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 einenchar
-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 einenchar
-Zeiger zu machen.Ich lese da
[i]text
, das ist offensichtlich ein Bug (i ist BB-Code für kursiv). Es muss einfachtext
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** istchar *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** istArgh, 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 :pMein 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 gutMuss 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ähltSo 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 solltechar *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 alsstrlen
undstrrchr
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/headerOldschool 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