Schleife
-
@AJ
ich kann deinen logischen aufbau vollkommmen nachvollziehen, komme aber leider mit den ganzen Stringfunktionen noch nicht so klar, und daher ist die Umsetzung deiner "Anleitung" auch gar nicht so einfach für mich (bin ja auch noch nícht solange im Geschäft).
Ich werde aber noch mal versuchen das hinzubekommen. Danke
-
@AJ
Kannst du mir evtl. noch einen Ansatz programmieren? So bis zu deinem 3. oder 4. Punkt? Weiß irgendwie trotz Anleitung nicht, wie ich richtig anfange (zu blöd). Ich hoffe, wenn ich nen Ansatz sehe, dann gehts.
Das mit dem 1. ist OK: (char* prt = strstr(in,re))
Aber jetzt gehts schon los: Wie kriege alles vor dem Suchstring in buffer???
evtl. so??? strncpy(buffer,in,petr-in) ?????? Keine Ahnung...
-
Ok ich mach dir mal den Anfang:
... char *pos, *altpos; int len; ... //Deine vorherigen Abprüfungen //Suche Suchstring in Text pos = strstr(in, re); //Speichere alte Position (hier Anfang) altpos = in; //Buffer initialisieren *buffer = 0; //Solange der Suchstring in Text gefunden wird while(pos) { //Merke Länge von buffer len = strlen(buffer); //Kopiere von alter Position bis Position des Suchstrings nach buffer strncat(buffer, altpos, pos-altpos); //Stringendezeichen setzen buffer[len+pos-altpos] = 0; //Hier muss noch ein wenig was gemacht werden ;) ... //Position nach Suchstring in Text ermitteln altpos = pos + strlen(re); //Suche nach weiteren Suchstring in Text hinter letzten gefundenen Suchstring pos = strstr(altpos, re); } //Hänge Rest von Text an Buffer an strcat(buffer, altpos); ...
-
Ich seh gerade das er hier auch gepostet hab. damit das nicht in 100 verschiedenen threads diskutiert wird und jeder 30 mal das gleiche sagt.(Ich glaub in unserem Forum sind auch schon 3 threads zu diesem thema offen). aktuell gehts gerade hier weiter fals noch jemand was dazu beisteuern will
http://www.fun-soft.de/showtopic.php?threadid=6950&post_start=10&time=1082990889
-
@ Windalf
Wie kann ich den bisherigen Code von dir noch ändern, damit auch ein größerer String eingefügt bzw. ersetzt werden kann???
P.S. Sorry, aber dies ist dann die letzte Frage zu dem Thema.
Ich habe schon versucht das inp-array zu vergrößern, was aber auch nicht funktionierte.
Ich meine wenn ich den String durch einen kleineren ersetze funktioniert es astrein. Aber es muss nicht zwangsweise ein kleinerer String ersetzt werden und deshalb wollte ich mir die Mgl. offen halten, auch diesen durch einen größeren zu ersetzen.P.S. Bitte um letzte Hilfe
-
Sorry, hier natürlich noch der bisherige code:
int ersetzen(char *such, char *neu, char *inp){ int flag,rv=0; char *p,*q,*r,*tmp; tmp=new char[strlen(inp)+1]; for(p=inp;*p;++p){ flag=1; for(q=such,r=p;*q&&*r&&flag;++q,++r)if(*q-*r)flag=0; if(flag){ for(q=tmp;*r;++q,++r)*q=*r; *q='\0'; for(q=neu,r=p;*q;++q,++r)*r=*q; for(q=tmp;*q;++r,++q)*r=*q; *r='\0'; ++rv; } } delete [] tmp; return rv; }
-
new
deleteSomit hat das nichts mehr mit ANSI-C zu tun. Ab damit nach C++. Außerdem ist der Quellcode unübersichtlich und nicht mal kommentiert *mecker*(hat aber seine Gründe!).
-
@AJ
also wenn dich das new und delete so stört mach ein malloc draus.
als ob das jetzt ein wirkliches problem ist.
heute wohl ne nörgeltablette gefuttert@evil411_unlogged
da einfach nur inp überschrieben wird, musst du inp halt nur entsprechend gross allokieren nicht mehr und nicht weniger.
und wie gesagt wenn du rekursive ersetzungen vermeiden willst solltest du nach einer ersetzung auf p nach ein strlen(neu) draufaddieren.so damit es hier im forum verweilen kann ein kleiner patch
int ersetzen(char *such, char *neu, char *inp){ int flag,x=strlen(neu),rv=0; char *p,*q,*r,*tmp; tmp=(char*)malloc(sizeof(char)*(strlen(inp)+1)); for(p=inp;*p;++p){ flag=1; for(q=such,r=p;*q&&*r&&flag;++q,++r)if(*q-*r)flag=0; if(flag){ for(q=tmp;*q++=*r++;); for(q=neu,r=p;*r++=*q++;); for(q=tmp,--r;*r++=*q++;); p+=x; ++rv; } } free(tmp); return rv; }
ach so und an sonsten zeig doch mal wie du ein inp-array definiert hast. bzw. wie du versucht hast es zu vergrössern
-
Windalf schrieb:
heute wohl ne nörgeltablette gefuttert
Anscheinend...
Mich stört der ganze Umstand einfach. Da wird an verschiedenen Stellen nachgefragt und dann werden die Lösungen wild durcheinander geschustert *kopfschüttel*.
Außerdem ist dieser Quellcode mehr als misserabel zu lesen und das stört mich noch viel mehr. Warum hat der Ersteller nicht gleich alles in eine Zeile gepresst??Ich hab auf jeden Fall keine Lust mehr einmal an der Version rumzudoktern, dann an einer ganz anderen Version, weil jemand anderes irgendwo wieder eine andere Lösung hat und auf einmal diese übernommen wird usw.
-
Ja, das mit dem new und dem delete ist schon in Ordnung.
Das ist ja nicht das Hauptproblem, sondern den String irgendwie ersetzen...
den inp-String bzw. das inp-array (char inp[MAX_LEN] --> MAX_LEN =100000) wird mit fgets aus einer Datei eingelesen. Wie mache ich denn nun das mit dem Array allokieren?. Wie groß muss denn das Array sein???
-
**@AJ & Windalf
**Es tut mir wirklich leid, wenn ich euch solche Schwierigkeiten bereite. Ich atme nun mal noch nichts so lange die C/C++-Luft ein, was heißen soll, dass ich ziemlicher Anfänger bin.
Da ich mich zwischen verschiedenen Lösungsvorschlägen nicht entscheiden konnte (PS: bin froh, wenn überhaupt eins funzt) habe ich ab und zu gewechselt. Weiterhin wusste ich bis gestern auch nicht, dass diese beiden Foren so eng zusammenarbeiten.
Auf jeden Fall tut es mir leid, dass ich immerzu einen neuen Thread angelegt, bzw. immer die selbe Frage zu unterschiedlichen Codes gestellt habe.
Ich weiß es ist für euch nicht einfach. Auf jeden Fall wird so etwas nicht mehr vorkommen und ich bedanke mich trotzdem für eure Hilfe.
Also Danke und Sorry, bis zum nächsten "einmaligen" Thread
-
@AJ
öhm, der Ersteller war ich
warum ichs nicht in eine zeile gepresst habe. weil ichs dann nicht mehr lesen kann, so wie es jetzt ist komm ich gut mit klar.mal davon abgesehen das die variablennamen nicht sprechend sind, was ist an dem code sonst auszusetzen?
@evil411
angenommen du ersetzt ein wort aus 3 buchstaben gegen eines aus 5, dann ist dein text am ende anzahl der ersetzungen*2 länger als der vorherige.
zum testen könntest du jetzt einfach mal doppelte bufferlänge die du für deinen text brauchst nehmen. das wird in den meisten fällen reichen. an sonsten müsstest du in der funktion ggf speicher mit realloc nachallokieren, falls der grösse des buffers nicht ausreichen sollte.so falls ich in meiner funktion kein fehler gemacht habe (kann man ja auch nicht ausschliessen und getestet hab ichs auch nicht gross) musst du das einfach nur in der art benutzen.
int laenge_text=100000; char *text = malloc(sizeof(char)*2*laenge_text); sprintf(text,"%s","tralalalalala 1234 abc usw....");//oder was auch immer du da in den string reinballern willst printf("%s\n",text); ersetzen("1234","xyz",text); printf("%s\n",text);
-
Windalf schrieb:
mal davon abgesehen das die variablennamen nicht sprechend sind, was ist an dem code sonst auszusetzen?
Du hast keinerlei Kommentare drin, was generell schlecht ist.
Und ich hab deswegen gefragt, warum du nicht gleich alles in eine Zeile schreibst, weil du for() if() und eine Anweisung direkt hintereinander hast. Was zumindest ich persönlich als sehr unübersichtlich emfinde. Es wirkt einfach zusammengepresst und unübersichtlich.Etwas mit dem ich auch nicht klarkomme, ist die Schreibweise der { am Ende einer Zeile, also z. B. direkt hinter if. Ich hab da immer das Problem, dass ich diese Klammer schlichtweg überlese und mich dann über eine } weiter unten wundere. Aber das ist wohl eher ein Problem von mir ;).
Zum Problem mit inp und des reservierten Speichers:
Man könnte inp auch als Zeiger auf einen Zeiger übergeben (**) und in der Funktion mir realloc() bei Bedarf vergrößern. Die aktuelle Größe von inp wäre dann natürlich auch nützlich ;).
-
Wie könnte ich das mit dem realloc noch einbauen? Wenn ich die Größe verdopple, funzt es leider nicht...
-
int ersetzen(const char *such, const char *neu, char **inp, int *inp_len) { ... //Wenn die Anzahl der Zeichen, die in inp gespeichert werden sollen, mehr sind //als in inp passen if(... >= *inp_len) { //um 1024 Byte vergrößern (kann auch eine andere Größe sein) *inp_len += 1024; //größeren Speicherplatz reservieren *inp = realloc(*inp, *inp_len); //Prüfung ob Reservierung geklappt hat if(!*inp) { //Kein Speicher mehr verfügbar, also raus! //(davor evtl. noch Sachen machen, die beim Beenden wichtig sind, z. B. free()) exit(1); } } ... }
-
Bei realloc bekomme ich immer einen Fehler von wegen:
Konvertierung des Parameters 1 von 'char' in 'void *' nicht moeglich
... obwohl mein 1.Parameter *inp ist. Müsste doch eigentlich hinhauen oder??
-
Quatsch was ich da geschrieben hab.
Zeig mal deine komplette Funktion. Hast du bei den Parametern, speziell bei inp, auch zwei * also ** gemacht??
-
kann jemand zufällig hier noch ein realloc einbauen, so dass es evtl funzen könnte? Ich bekomme ja bei meinen Versuchen die allerschärfsten Fehler...
Ich ersetze immer 4 Zeichen des Strings durch 10 Zeichen. Aber sobal der neue grösser als der alte String ist, geht nichts mehr:int ersetzen(char *such, char *neu, char *inp) { int flag,num=0; //rv beinhaltet wieviele ersetzungen gemacht wurden int laenge_text = STR_MAX; char *p,*q,*r, *buffer; buffer =(char*)malloc(sizeof(char)*(strlen(inp)+1)); //buffer zum umkopieren allokieren for(p=inp;*p;++p) //für jedes zeichen des inputs { flag=1; for(q=such,r=p;*q&&*r&&flag;++q,++r) //checkt ob such ab der stelle wo p gerade steht im string ist { if(*q-*r)flag=0; //wenn ja ist flag nach dem schleifendurchlauf auf 1 sonst 0 } if(flag) //wenn zu ersetzender text gefunden { for(q=buffer;*r;++q,++r) //kopiere das was nicht überschrieben werden solll in den buffer { *q=*r; } *q='\0'; for(q=neu,r=p;*q;++q,++r) //schreibe das neue wort an die aktuelle stelle { *r=*q; } for(q=buffer;*q;++r,++q) //kopiere das im buffer gesicherte zurück hinter die ersetzte stelle { *r=*q; } *r='\0'; ++num; } } free(buffer); //buffer wieder freigeben return num; }
-
Zum Problem mit inp und des reservierten Speichers:
Man könnte inp auch als Zeiger auf einen Zeiger übergeben (**) und in der Funktion mir realloc() bei Bedarf vergrößern. Die aktuelle Größe von inp wäre dann natürlich auch nützlich .jo da hatte ich keine lust mehr drauf
anfangs wollte er ja nur einen ansatz...
das hier ist übrigens ne üble sache
*inp = realloc(*inp, *inp_len);
sollte man nicht tuen weil wenn realloc fehl schlägt hat man ein memoryleak.
besser ist es erst auf nen tmp-zeiger realloc zu verwenden und denn dann auf NULL zu checken bevor man dann *inp=tmp; zuweist... wenns nicht geklaptt hat zeigt dann inp immer noch auf den speicherbereich den man vorher hatte, an sonsten hängt der speicher verloren "rum"
-
Könntest du mal die realloc() in deinen Code mit einbauen? Ich weiß nicht was ich falsch mache, aber ich kriege diese Funktion nicht in "deinem Code" unter
Würde mich echt freuen wenn du diese ein bis zwei zeilen noch dazuschreiben könntest, du kennst dich doch mit deinem Code am besten aus. *SCHNIEF*
und ich möchte irgendwie dieses sch... Thema abschließen.Danke, Gruss Evil411_unlogged