Arrayelement löschen



  • #include <cstring>
    
    // ...
        char narf[] = "Was auch immer...";
    
        std::memmove(narf, narf+1, sizeof(narf)-1);
        narf[strlen(narf)-1] = 0;
    

    Aber solltest doch eher wenn möglich von Char-Arrays weg und hin zu C++-Strings in Kombination mit den STL-Funktionen...



  • Ok also verschieben würde dann aus (2+2)\0
    ein 2+2)_\0 machen versteh ich das richtig?

    das ja irgendwie doof

    mhh wenn ich jetzt die hintere KLammer wegkriegen würde (wenn ich wüsste wie ich das Array verschiebe) ist es ja grundlegend egal ob da dann zwei leere Elemente stehen dann der NULL Terminator kommt glaube ich.

    Rechnen müsste er ja trotzdem dann 2+2



  • Durch die letzte Zeile meines Beispielcodes wird am Ende ein Zeichen abgeschnitten.



  • Fellhuhn schrieb:

    Aber solltest doch eher wenn möglich von Char-Arrays weg und hin zu C++-Strings in Kombination mit den STL-Funktionen...

    ja ich weiß!

    MAche es ersteinmal ohne den Strings sondern mit Standart Char Array.
    deshalb ist jede lösung ohne String erstmal wichtig für mich 🙂

    ideen sind gefragt

    aber danke für den ersten Denkansatz für mich 🙂



  • Virokams schrieb:

    Ok also verschieben würde dann aus (2+2)\0
    ein 2+2)_\0 machen versteh ich das richtig?

    Nein.

    Aus "(2+2)\0" macht er "2+2)\0\0" mit dem memmove und mit der Zeile danach folgendes: "2+2\0\0\0". Im Endeffekt ist es also nur noch "2+2" (auch wenn der Speicher für die drei \0 immernoch belegt ist).



  • Fellhuhn schrieb:

    Virokams schrieb:

    Ok also verschieben würde dann aus (2+2)\0
    ein 2+2)_\0 machen versteh ich das richtig?

    Nein.

    Aus "(2+2)\0" macht er "2+2)\0\0" mit dem memmove und mit der Zeile danach folgendes: "2+2\0\0\0". Im Endeffekt ist es also nur noch "2+2" (auch wenn der Speicher für die drei \0 immernoch belegt ist).

    ich probiers mal aus...

    das memmove() lässt sich auch auf ein normalen Char Array[] anwenden?



  • Jepp. memmove ist noch ein Relikt aus C-Zeiten.

    Mit C++ wäre es wohl eher etwas in der Form von:

    std::string newString(oldString.begin()+1, oldString.end()-1);
    


  • Ma Ausprobiert... und:

    if (w1[0] == '(' && sizeof(w1)-1 == ')')
    	{
    		std::memmove(w1, w1+1, sizeof(w1)-1);
    		w1[strlen(w1)-1] = 0;
    	}
    	else if(w2[0] == '(' &&  sizeof(w2)-1 == ')')
    	{	
    		std::memmove(w2, w2+1, sizeof(w2)-1);
    		w1[strlen(w2)-1] = 0;
    	}
    

    Es klappt nicht so ganz...

    ich gebe als Bsp. 2*(2+2) w1 = 2 w2= (2+2) o= *

    Selbst wenn das bei w1 ginge... (programm startet wenn ich else if Auskommentiere
    tu ich es nicht:

    krieg ich nen Fehler weil:

    char w1[512]; memset(w1, 0, sizeof(w1)*sizeof(char));
    	const char* w2;   // memset(w2, 0, sizeof(w2)*sizeof(char));  
    	char o[8];    memset(o , 0, sizeof(o )*sizeof(char));
    
    		// Alles was links vom Trenner steht in W1 was rechts steht W2 Operator in o
    		strncpy (w1, term, trenner);
    		w2 = term + trenner+1;
    		o[0] = term[trenner];
    		printf ("w1: %s \n", w1);
    		printf("w2: %s \n",w2);
    		printf("o: %s \n",o);
    

    krieg ich konflikt mit Zeile 2 (const Char* w2;)
    und
    halt weil ich es so brauche für (w2 = term + trenner+1)

    ... Freaky



  • if (w1[0] == '(' && sizeof(w1)-1 == ')') // hier meinst du wohl eher w1[strlen(w1)-1]
    	{
    		std::memmove(w1, w1+1, sizeof(w1)-1);
    		w1[strlen(w1)-1] = 0;
    	}
    	else if(w2[0] == '(' &&  sizeof(w2)-1 == ')') // siehe oben
    	{	
    		std::memmove(w2, w2+1, sizeof(w2)-1);
    		w1[strlen(w2)-1] = 0; // w2 statt w1?
    	}
    


  • Fellhuhn schrieb:

    if (w1[0] == '(' && sizeof(w1)-1 == ')') // hier meinst du wohl eher w1[strlen(w1)-1]
    	{
    		std::memmove(w1, w1+1, sizeof(w1)-1);
    		w1[strlen(w1)-1] = 0;
    	}
    	else if(w2[0] == '(' &&  sizeof(w2)-1 == ')') // siehe oben
    	{	
    		std::memmove(w2, w2+1, sizeof(w2)-1);
    		w1[strlen(w2)-1] = 0; // w2 statt w1?
    	}
    

    stimmt... copy Pastefehler bei w1 statt w2 und mit dem sizeof ... war ich mir nicht sicher danke für die Korrektur...

    nun hab ich es laufen lassen und die Fehlemeldung ist

    Fehler 6 error C2664: 'memmove': Konvertierung des Parameters 1 von 'const char *' in 'void *' nicht möglich

    Fehler 7 error C3892: "w2": Einer Variablen, die konstant ist, kann nichts zugeordnet werden

    wie gesagt das liegt wohl an:

    const char* w2;
    

    was ich aber so brauche für:

    w2 = term + trenner+1;
    

    mhhh oder?



  • const char macht nur dann Sinn wenn du auch nichts verändern willst.

    Also entweder kein const verwenden oder in ein neues (nicht const) Char-Array kopieren.



  • so habs zum laufen bekommen danke 🙂

    jetzt hab ich ein anderes Problem 😛 aber zu 80% läuft mein Projekt schonmal 🙂

    Danke nochmal



  • Hast du auch an "(2+2)(3+3)" gedacht? Würde bei dir jetzt "2+2)(3+3" rauskommen.



  • Fellhuhn schrieb:

    Hast du auch an "(2+2)(3+3)" gedacht? Würde bei dir jetzt "2+2)(3+3" rauskommen.

    GENAU das ist mein nächstes Problem...

    ich gebe ((2+2)*2) ein und es kommt 0 raus... funzt net... ist klar weil er NUR anfängt + oder so zu beachten wenn Klammern= 0 sind...

    int strich = -1;	// Strichoperator gefunden wird strich zum Wert der Stelle wo gefunden
    	int punkt = -1;		// Strichoperator gefunden wird strich zum Wert der Stelle wo gefunden
    	int klammern = 0;	// Klammer erhöhrt sich wenn Klammerauf und senkt sich wenn Klammerzu
    
    	for ( int i = 0; term[i] != '\0'; i++)
    	{
    		if ((term[i] == '+' || term[i] == '-') && klammern == 1)
    		{
    			strich = i; // Stelle an der das + oder - im string steht wird in var strich gespeichert
    			break;
    		}
    		else if ((term[i] == '/' || term[i] == '*') && klammern == 0)
    		{
    			punkt = i;  // Stelle an der das * oder / im string steht wird in var punkt gespeichert
    		}
    		else if (term[i] == '(')
    		{
    			klammern++; //Wenn Klammerauf gefunden klammern++
    		}
    		else if (term[i] == ')')
    		{
    			klammern--; //Wenn Klamerzu gefunden klammern--
    		}
    


  • Wenn es dir um die Klammern geht, solltest du im String die letzte öffende Klammer suchen. Von da an suchst du dann die erste schließende. Dann hast du schon einmal den "innersten Term". Den löst du auf und rechnest dann genauso weiter.



  • Fellhuhn schrieb:

    Wenn es dir um die Klammern geht, solltest du im String die letzte öffende Klammer suchen. Von da an suchst du dann die erste schließende. Dann hast du schon einmal den "innersten Term". Den löst du auf und rechnest dann genauso weiter.

    irgendwie so muss ich das wohl mal angehen...

    *stark nachdenk* XD



  • Ich brauch glaube ich einen Idee anstoß

    wär nett 🙂

    Danke



  • Nicht schön, nicht perfekt, aber funzt (bei richtigen Eingaben):

    Verwendet allerdings C++-Strings und StringStreams zwecks Konvertierung. Damit du aber noch was zu tun hast erklär ich nichts und hast was zu knobeln. 🙂

    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <sstream>
    
    using namespace std;
    
    double calc(string t){
        int p = t.find_first_of("+-/*", 1);
    
        stringstream ss1(t);
        double v1;
        ss1 >> v1;
    
        stringstream ss2(string(t.c_str() + p + 1));
        double v2;
        ss2 >> v2;
    
        switch(t[p]){
    	case '+': return v1+v2;
    	case '-': return v1-v2;
    	case '*': return v1*v2;
    	case '/': return v1/v2;
        }
        cerr << "Verstehe das nicht: '" << t << "'!" << endl;
        return 0;
    }
    
    int main(){
        string term;
    
        cout << "Term eingeben?" << endl;
        cin >> term;
    
        int i, j;
        do{
    	i = term.find_last_of('(');
    	if (i != string::npos)
    	{
    	    j = term.find_first_of(')', i);
    	    if (j == string::npos){ 
    		cerr << "Verstehe das nicht: " << term << endl; 
    		break; 
    	    }
    	    string part(term.begin() + i + 1, term.begin() + j);
    	    double value = calc(part);
    	    stringstream v;
    	    v << value;
    	    string rep = v.str();
    	    term.replace(term.begin()+i, term.begin()+j+1, rep);
    
    	    cout << "== " << term << endl;
    	}else break;
        }while(true);
    };
    


  • ok danke XD

    wenn ich das mal mit den Strings verstehe versteh ich den vorgang bestimmt auch 🙂

    bin das gerade an am meinem Quellcode am probieren... wenns nicht klappt mus swohl mein Ausbilder wieder herhalten 😃



  • Ein String ist auch von der Handhabe nicht großartig anders als ein C-Array, bietet nur einfach ein paar sinnvolle Funktionen wie find() usw. Aber die kannst du auch mit Char-Arrays leicht nachbilden.

    Das Prinzip ist einfach:
    1. Finde eine Klammer ohne weitere Verschachtelung
    2. Seperiere dessen Term und rechne den aus
    3. Ersetze den Teil an dem vorher der Term + Klammern stand durch das Resultat
    4. gehe zu 1

    Punkt 3 dürfte etwas triggy sein, dafür solltest du jedesmal ein neues char-Array anlegen, sonst kann es bei größeren Berechnungen vorkommen das der alte Platz für das Resultat nicht reicht (oder? *grübel* naja, sicher beim Teilen).


Anmelden zum Antworten