STRESS mit C/C++ Hilfe!!!!



  • User--- schrieb:

    Ich war mal so nett (na gut eher gelangweilt =)) und hab dir das Grundgerüst für Aufgabe1 gemacht, extras wie nen - oder + vor der Zahl und Längenbegrenzung musst allerdings du einfügen.

    Und wieso verwendet dein Lehrer keine Referenz für den Integer 'wert'?

    bool stringToInt (char* str, int* wert)
    {
    	*wert = 0;
    
    	for( int i = strlen( str ) - 1, pow = 1; i >= 0; --i, pow *= 10 )
    	{
    		if( isdigit( str[ i ] ) )
    		{
    			*wert += ( ( str[ i ] - 48 ) * pow );
    		}
    		else
    		{
    			return false;
    		}
    	}
    
    	return true;
    }
    

    frickler 👍



  • Und was soll diese Funktion genau bewirken? 😞



  • Ich bringe es einfach nicht fertig.Bitte Hilfe....Danke 😡



  • ähm...nein?

    präsentier uns erstmal deine überlegungen, und sag uns, was du nicht kannst. Dann können wir deine Lücken schließen. Wir könnten dir das programm zwar jetzt lösen, aber was dann? die nächsten aufgaben werden garantiert nicht leichter, und du wirst uns wieder um hilfe bitten müssen...aber werden wir dir ewig helfen wollen?



  • Ok Also. Um ehrlich zu sein verstehe ich die Aufgabenstellung nicht richtig. Ich soll ein strin wert eingeben und es soll es dann als int wert ausgeben. Indem es in der ASCI tabelle durchsucht und den wert ausgibt? oder soll es einfach den wert überprüfen und wenn es von 0-9 ist true, alles andere false?
    Ich brauche einen startpunkt von was ich ausgehen kann und ein funktionprototyp ist nicht gerade das was ich will.klar hast du recht. ich will es auch lernen und es fertig bringen, aber bei mir hat es noch nicht klick gemacht. wie könnte ich den stoff richtig lernen?Danke



  • OK, gehen wir mal die Aufgabe 1 durch. Vielleicht macht's ja dann klick.

    Schreiben Sie eine Funktion, die einen String

    String ist hoffentlich klar, oder? Letztendlich ist das nichts anderes wie eine Sequenz von Zeichen. Es gibt verschiedene Repräsentationen von Strings, wie zB C-Strings. Das ist aber ein Detail der Implementierung, darum kümmern wir uns später. Und durch den Funktionsprototyp hat euch der Lehrer ja bereits C-Strings vorgegeben, also old-style nullterminiert.

    in einen echten int-Wert umwandeln kann.

    Dürfte eigentlich auch klar sein. Dafür steht uns der Typ int zur Verfügung. 🙂 Warum im Funktionsprototyp ein Zeiger auf int übergeben wird, liegt daran, dass in C++ Parameter by-value übergeben werden. Alles was du damit in der Funktion machst, überträgt sich somit nicht nach aussen. Deshalb der Zeiger (obwohl es in C++ dafür eigenlich Referenzen gibt), damit wir den äusseren int Wert ändern können. Stichwort: Dereferenzieren.

    Die Funktion muss also den String Zeichen für Zeichen untersuchen und aus den gefundenen
    Ziffern „irgendwie“ den numerischen Wert erstellen.

    Dazu solltest du dir mal Zahlensysteme anschauen und wie diese funktionieren. Jedem Zahlensystem liegt eine Basis zu Grunde (zB dezimal ➡ 10). Und die Wertigkeit jeder Ziffer wird entsprechend durch die Basis bestimmt. Jedes Zeichen unseres Strings ist so eine Ziffer. Was du nun machen musst, ist, jedes Zeichen unseres Strings zu separieren und entsprechend der Basis die Wertigkeit zu bestimmen. Dann addierst du einfach alles auf, um den Gesamtwert (für unser int) zu bekommen. Nur mal als kleinen Gedankenanstoss:

    [b]12345[/b] = [b]1[/b] * 10000 + [b]2[/b] * 1000 + [b]3[/b] * 100 + [b]4[/b] * 10 + [b]5[/b] * 1
    

    Ein Problem hierbei ist, die Zeichen unseres Strings in ihren numerischen Wert umzuwandeln. Bedenke '1' != 1. Hier hilft dir aber die ASCII Tabelle weiter.

    Wenn die Funktion ihre Arbeit nicht korrekt
    beenden kann, weil z.B. ein ungültiges Zeichen gefunden wird, soll sie ihre Arbeit abbrechen
    und einen Fehler zurück melden.

    Tja, auch das sollte eigentlich klar sein. Hier hilft, dass du einfach jedes Zeichen unseres Strings prüfst, ob es eine passende Ziffer entsprechend unserer Basis sein kann. Wenn nicht, dann gibts halt ein return false.

    Der Prototyp der Funktion soll so aussehen:
    bool stringToInt (char* str, int* wert);

    Ehrlich gesagt, kein schöner Prototyp. Mach zumindest

    bool stringToInt (const char* str, int* wert);
    

    daraus. Und wenn dein Lehrer meckert, dann verweise ihn auf diesen Thread bzw. dieses Forum. 😉

    Hierbei ist str ein Zeiger auf den String, der umgewandelt werden soll, wert ist ein Zeiger auf
    eine int-Variable, in die der gefundene Wert gelegt werden soll. Wenn ein Fehler auftritt, gibt die
    Funktion als Rückgabewert false zurück. In diesem Fall darf der Wert, worauf der Zeiger
    wert zeigt, nicht verändert werden. Wenn alles geklappt hat, gibt die Funktion true zurück.

    Auch das verrät uns schon ein Implementationsdetail. Kleiner Tipp, wir führen unsere Umwandlung in einer temporären int Variable durch und schreiben wert erst am Ende, sofern keine Fehler auftraten.

    Gültige Zeichen für einen int-Wert sind die Zifferzeichen 0 – 9 und eventuell an erster Stelle ein
    Minuszeichen.

    Nicht ganz korrekt. int ist einfach ein Typ für Ganzzahlwerte, vollkommen wertungsfrei bzgl. des Zahlensystems. Wahrscheinlich will euch euer Lehrer damit einfach sagen, dass ihr das dezimale Zahlensystem verwenden sollt.

    Beachten Sie zudem, dass ein String nicht beliebig lang sein darf, int-Werte können nicht
    beliebig gross werden.

    Den ersten Teil des Satzes kannst du getrost ignorieren, den zweiten nicht. Überlauf ist eben ein weiterer Aspekt der Fehlerbetrachtung. Darüber würde ich mir aber erst am Ende Gedanken machen, zumal das etwas tricky ist. Zuerst sollte mal der grundlegende Algo stehen.



  • ___



  • Ohne den Code jetzt im Detail durchgeschaut zu haben, sieht doch schon mal nicht schlecht aus. Alles was ich dir dazu sagen kann, ist, testen, testen, testen.
    Und hier

    if(*str = '-')
    

    hat sich unser const schon ausgezahlt. Der Compiler sollte dir einen Fehler bringen und dich, darüber nochmal nachzudenken (= != ==).



  • Ich bekomme beim compilieren einen Fehler genau an dieser Stelle if(*str='-')
    Die Nachricht lautet: 32 > assignment of read-only location <

    Und was könnte ich im Basisprogramm für Testwerte eingeben Zbs?Danke



  • ----



  • Du dereferenzierst hier

    if (*str == wert )
    

    den Pointer auf eine char-Variable und vergleichst ihn dann mit nem Zeiger auf einen double wert, den du oben im Funktionsprototyp vereinbart hast. Und weil du eine Zahl mit einer Speicheraddresse vergleichst meckert er.



  • Was kann ich dagegen tun?



  • jerico schrieb:

    Was kann ich dagegen tun?

    beginnst du bitte mal, selber zu denken?

    btw: es wäre schön, wenn du deinen code wieder reineditieren würdest, so hat das ganze einen Kristallkugel character



  • Ich weiß nich was du mit der Zeile anfangen willst, aber entweder du hast Wert mit großem W gemeint, dann musst du das natürlich hinschreiben, oder du hast wert mit kleinem W gemeint, dann musst du den Pointer dereferenzieren. Aber da kann man ehrlich gesagt auch selbst draufkommen.

    MfG



  • -.--



  • --



  • die zweite funktion (test) ist doch ueberfluessig, probiers mal so:

    int main() {
       char test[15]="345";
       int wert=0;
    
    if (stringToInt(test,&wert))
       cout<<test<<" ok, wert ist: "<<wert<<endl;
    else
        cout<<test<<" ungueltig\n";
    
    system("pause");
    }
    

    die funktion stringToInt gibt doch mit true/false zurueck, ob der wert ok ist ?!



  • Funktioniert nicht.



  • int W = 5;
    

    😕

    Sollte das nicht

    int W = 0;
    

    sein?



  • Ich habe mich erbarmt deinen Code so zu verändern das mindestens die erste
    Aufgabe bei dir erledigt ist, ich hab ihn auskommentiert, das soll für dich keine geschenkte Lösung sein.

    Vielmehr solltest du versuchen die Kommentare zu lesen und auch zu verstehen, wenn du das Prinzip was dahinter steckt richtig erkannt hast, bin ich mir sicher wirst du den Rest auch selber lösen können, eine 100% Lösung will ich dir nicht
    geben, davon hättest du nichts. Keinen Lerneffekt etcetera...

    Hoffe das du damit was anfangen kannst,
    falls du noch Fragen hast stell sie bitte

    Diesen Code könnte man noch viel kompakter machen, aber der Einfachkeithalber damit du ihn besser verstehst habe ich ihn ziemlich weit ausgedehnt 😉

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    bool stringToInt(const char * str, int * wert);
    
    int main()
    {
        char test[15]="0000148080";
        int wert=0;
        if (stringToInt(test,&wert))
        {
            cout<<test<<" ok, wert ist: "<<wert<<endl;
        }
        else
            cout<<test<<" ungueltig\n";
    
        system("pause");
    
    }
    
    bool stringToInt(const char * str, int * wert)
    {
        // Nullwert überprüfen
        if(str == NULL)
            return false;
    
     //   if(wert == NULL)  // hab ich ausgeklammert, ist vollkommen unsinnig,
     //   return false;     // wieso sollte die Funktion verlassen werden wenn
                            // wert = NULL ist?? Bitte Begründung :)
    
        // Vorzeichen erkennen und überspringe
        int vorzeichen = 1;
        if(*str == '-')
        {
            vorzeichen = -1;
            str++;
        }
        // Das ist soweit ok, wobei du dafür auch short int verwenden könntest, ist aber dir überlassen
    
        // Eigentliche Zahl lesen
    
        // Die gesamte While Funktion habe ich gelöscht da sie zwei schwere Fehler enthielt.
    
        //1. Du hast den Faktor W nicht ausschliesslich mit Faktor 10 multipliziert um eine
        // Zahl höher zu kommen, das ist aber beim Dezinmalen Zahlensystem notwendig (Faktor 10)
    
        //2. Hast du von vorne nach hinten angefangen, was dir überhaupt nix bringt (so wie du das vorhattest)
        //denn: woher soll das Programm wissen das z.B. bei der Zahl 5600, die 5 den Faktor 1000 hat(10*10*10)
        //und die 6, z.B. den Faktor 100 hatte, das geht aus deiner Funktion überhaupt nicht hervor
    
        //hier mal so in kurzen Ansätzen wie du die Aufgabe für dich hoffentlich verständlich lösen kannst ;)
    
        int index;  // eine Variable um durch das Array durchzustöbern
        int W;      // deine Faktor-Variable
        for(index = 0;str[index]!= '\0';index++);   // diese Schleife spult den index bis zum Ende des Stringes
                                                    // bei der Zahl 5600 wäre dies die Stelle nach der letzen Null
        index--;                                    // jetzt verminderst du den index, du bist nun bei der ersten Zahl
                                                    // die den Faktor 1 hat, (Dezimal), die erste 0 bei 5600
    
        for(W = 1;;index--,W*=10)         // Der Kopf der Schleife macht grundlegendes: für jede Zahl die du
        {                                           // nach oben gehst (index) wird der Faktor um 10 multipliziert, d.h. z.B.
                                                    // wenn das Programm bei der 6 ankommt enthält W den Wert 100 ;)
            if(str[index] < '0' || str[index] > '9')  // das war völlig ok, habe es nur halt mit arrays gemacht
            {
                return false;
            }
            else            // etwas verändert ;)
            {
                *wert += W*(str[index]-'0');   // beim Beispiel 4 würde er 4*100 = 400 zu dem Wert hinzuzählen, bei 5 + 5000
            }
    
            if(index == 0)      // Wenn index den Wert 0 erreicht hat, verlasse Schleife
            {
                break;
            }
        }
    
        *wert *= vorzeichen; //Vorzeichen negativ oder positiv ;) nur mit Vorzeichen
    
        return true;    // alles bis hier ok, hoffe es war verständlich und du kommst jetzt damit besser zurecht :)
    }
    

    //EDIT

    achso, und benutz bitte Code-Tags, das macht deinen Code übersichtlicher, und bitte schreib nicht Beiträge wo nur ein '--' oder ähnliches zu sehen ist.

    Das ist nicht Sinn und Zweck der Sache...


Anmelden zum Antworten