Schleife



  • @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"



  • @Windalf

    😞

    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



  • @Windalf
    Schau mal was ich danach mache :). Wenn das Programm noch weiterlaufen soll, hast du natürlich recht. Allerdings macht es da wenig Sinn, da es ja die Aufgabe nicht richtig vollenden kann.



  • Weiss wirklich niemand von euch, wie ich jetzt noch das realloc in den oben geposteten Quellcode bekomme.
    Mir platzt gleich der Schädel und es klappt noch nicht.
    Ich hoffe mir kann in der Hinsicht noch jemand weiter helfen. 😕 😕 😕 😕 😕 😕 😕 😕 😕



  • @evil411
    Ich habe auch noch andere Dinge zu tuen als den ganzen Tag im Forum zu gucken ob ich irgendwelche Fragen beantworten kann. zumindest nen Tag sollte man sich ggf. gedulden können

    so habs schnell zusammengehackt,
    ist jetzt super scheisse geworden der quellcode, einfach nur noch ein zusammengehacke sollte aber funzen, habs jetzt nicht gross getest

    int ersetzen(char *such, char *neu, char **inp,int *inp_l){ 
    int flag,a=0,x=strlen(neu),y=strlen(such),z=strlen(*inp),rv=0; 
    char *p,*q,*r,*tmp; 
        tmp=(char*)malloc(sizeof(char)*(z+1)); 
        for(p=*inp;*p;++p,++a){ 
            flag=1;     
            for(q=such,r=p;*q&&*r&&flag;++q,++r)if(*q-*r)flag=0; 
    
            if(flag){ 
    			z+=x-y;
    			if(*inp_l<=z){
    				q=(char*)realloc(*inp,sizeof(char)*(z+1));
    				if(q){p=q+a;r=p+y;*inp=q;*inp_l=z+1;}
    				else return -1;
    			}
    
                for(q=tmp;*q++=*r++;); 
                for(q=neu,r=p;*r++=*q++;); 
                for(q=tmp,--r;*r++=*q++;); 
                p+=x;
    			a+=x;
                ++rv; 
    
    		}     
    
        } 
        free(tmp); 
        return rv; 
    } 
    
    int main(){
    
    int inp_l=60;
    char *inp;
    
    inp=(char*)malloc(sizeof(char)*inp_l);
    
    sprintf(inp,"trlalala 1234 asdfasdf gmx 1234 ende feierabend 1234");
    
    printf("%s\n",inp);
    ersetzen("1234","abcdefghijklmnopre",&inp,&inp_l); 
    printf("%s\n",inp);
    free(inp);
    }
    


  • ja, mit diesem String funktioniert es. Aber wenn ich meinen String (char inp[100000]) nehme gehts nicht? Schnief!
    Woran könnte das evtl. noch liegen????



  • ja, mit diesem String funktioniert es. Aber wenn ich meinen String (char inp[100000]) nehme gehts nicht? Schnief!
    Woran könnte das evtl. noch liegen????

    klar gehts dann nicht. das hab ich dir doch schon mal geschrieben gehabt.
    wenn du diesen speicher konstanter grösser auf den stack packst, kannst du ihn nicht verändern. er ist nun mal konstant du kannst da nicht mehr an der grösse drehen. wenn du ein array variabler grösse brauchst, geht das in c nur mit malloc und realloc....

    da kannst du mit deinem char inp[100000] soviel rumprobieren wie du willst das wird nie funktionieren.

    mal davon abgesehen solltest du auf den stack keine array packen die viel grösser als 1000 sind sonst ist der irgendwann mal dicht und dein programm kackt ab.


Anmelden zum Antworten