string auf int überprüfen



  • Hallo zusammen,

    ich lese wie folgt einen string ein:

    string input;
    getline(cin, input);
    

    Ich möchte jetzt prüfen ob input eine Ganzzahl ist. In C gabs eine funktion isdigit(). Gibts was vergleichbares für die string-Klasse in C++?

    Lg
    Florentina





  • FAQ Lesen wäre was... "Einmal string nach Zahl und zurück"...



  • Oder aber fix selber gebaut 😃

    int stringToInt(char* buff){
    	int i = 0; /* Laufvariable - Von hinten nach vorn strung durchgehen */
    	int l = 0; /* Den Zeichenwert */
    	int m = 0; /* Summe */
    	int j = 0; /* Laufvariable - Dezimalstellenwert der Zahl */
    	int k = 0; /* Laufvariable - Dezimalstellen Multiplikator x^k */
    	char isANumber = 0;
    
    	for(i = strlen(buff)-1, j = 0; i >= 0; i--, j++){
    		/* Man will ja auch nur die Zahlen aus dem string haben */
    		if(buff[i] < '0' || buff[i] > '9')
    		{
    			/* Dezimalstellenwert wieder verringern, damit bei Zahlenbeginn */
    			/* auch der Dezimalstellenwert korrekt ist */
    			j--;
    			continue;
    		}
    
    		/* Auf die "echte" Zahl schließen */
    		l = buff[i]-'0';
    
    		/* Dezimalstellenwert der Zahl erhöhen */
    		for(k = 0; k < j; k++){
    			l *= 10;
    		}
    		isANumber = 1;
    		/* Aufsummieren */
    		m += l;
    	}
    
    	return isANumber == 0 ? m-1 : m;
    }
    

    könnte man auch so umbauen, dass wenn ein Buchstabe gefunden wird einfach ein false zurück geht und sonst, wenn alles komplett durchläuft true.
    Ich weiß warum das Rad neu erfinden und dann auch noch so abartig, aber ich sag darauf immer, warum nicht? 😛

    MFG
    Blackskyliner


  • Administrator

    Blackskyliner schrieb:

    Ich weiß warum das Rad neu erfinden und dann auch noch so abartig, aber ich sag darauf immer, warum nicht? 😛

    Weil es falsch ist? Zum Beispiel gibt es keine Garantie, dass die Zeichen 0 bis 9 hintereinander liegen müssen. Wodurch deine Überprüfung, ob es eine Ziffer ist, und deine Umrechnung von der Ziffer zur Zahl nicht Standardkonform sind und unter Umständen scheitern könnten.
    Zudem Weil deine Lösung sowas von C89 ist. Mit C++ oder modernem C hat das nicht viel am Hut.
    Und auch Dinge wie const-correctness fehlen völlig.

    Klar, es ist eine witzige Übung. Allerdings wenn man sie macht, sollte man sie schon korrekt machen. Für den produktiven Einsatz sollte eine Übung dann allerdings nicht herhalten müssen.

    Grüssli



  • Unser Professor meinte in der Vorlesung zu C++ das es erst seit C++ möglich sei einen Parameter Pointer und dessen daten als const zu deklarieren, da die Funktion ursprünglich für meinen C-Beleg war, fehlt diese const-correctnes. Aber ich werde es mir merken, dass es in neuen, bzw. aktuellen, Standards scheinbar doch möglich ist...

    Und was ist sonst noch so C89, bzw. kann mit dem aktuellen C99 Standard besser oder anders gemacht werden? Ich will ja eben durch solche Funktionen dazu lernen... Und zudem ist diese Funktion für heutige x86 Maschinen gedacht, bei denen dieses Schnipsel ja gut zu funktionieren scheint.

    Ohne jetzt threadnapping zu verursachen zu wollen...



  • Blackskyliner schrieb:

    Unser Professor meinte in der Vorlesung zu C++ das es erst seit C++ möglich sei einen Parameter Pointer und dessen daten als const zu deklarieren, da die Funktion ursprünglich für meinen C-Beleg war, fehlt diese const-correctnes.

    Das stimmt nicht, const gibts schon in C89.

    Blackskyliner schrieb:

    Und was ist sonst noch so C89, bzw. kann mit dem aktuellen C99 Standard besser oder anders gemacht werden?

    Es geht hier primär um C++ und nicht um C, da wir uns im entsprechenden Unterforum befinden. In C++ kann einiges besser gemacht werden.

    Zum Beispiel kannst du Variablen dann deklarieren, wenn sie benötigt werden. Oder du hast gekapselte Klassen, die ihre Speicherverwaltung selbst übernehmen. Stell dir mal eine umgekehrte Funktion in C vor (int nach String): Du musst entweder einen begrenzten Puffer übergeben und hast Probleme, wenn dieser zu klein ist, oder verschwendest Speicher, wenn er zu gross ist. Alternativ kannst du in der Funktion dynamisch Speicher anfordern und zurückgeben, dann muss sich aber der Aufrufer um die Freigabe kümmern. Du brauchst O(n), um die Länge eines Strings zu erhalten, statt O(1). Zumindest, wenn du die Schnittstelle nicht mit einem zusätzlichen Grössenparameter versiehst. Fehlerbehandlung ist ein weiterer Punkt. Was machst du, wenn stringToInt nicht funktioniert, weil kein int geparst werden kann? ERRNO setzen, auf das man überall manuell abfragen muss und bei dem die Gefahr besteht, dass es schon wieder durch einen anderen Fehler überschrieben wurde? Mit Exceptions hat man in C++ eine Möglichkeit, elegant Fehler zu behandeln.


  • Administrator

    Blackskyliner schrieb:

    Unser Professor meinte in der Vorlesung zu C++ das es erst seit C++ möglich sei einen Parameter Pointer und dessen daten als const zu deklarieren, da die Funktion ursprünglich für meinen C-Beleg war, fehlt diese const-correctnes. Aber ich werde es mir merken, dass es in neuen, bzw. aktuellen, Standards scheinbar doch möglich ist...

    Wie Nexus sagt, ist const seit C89 im C Sprachstandard. Allerdings war es damals nur eine Empfehlung. Ein Kompiler konnte das const ignorieren. Schadet trotzdem nicht, es zu machen. Und ich nehme mal an, dass aktuell Kompiler sowas prüfen. Wie es in C99 definiert ist, weiss ich nicht.

    Blackskyliner schrieb:

    Und was ist sonst noch so C89, bzw. kann mit dem aktuellen C99 Standard besser oder anders gemacht werden?

    In C99 kann man die Variable dann deklarieren, wenn man sie braucht. Man muss nicht alles am Anfang der Funktion deklarieren.

    Blackskyliner schrieb:

    Und zudem ist diese Funktion für heutige x86 Maschinen gedacht, bei denen dieses Schnipsel ja gut zu funktionieren scheint.

    Was meinst du mit x86? Meinst du wegen der nicht vorhandenen Garantie, dass die Buchstaben 0 bis 9 hintereinander liegen? Das hat nichts mit x86 zu tun! Das liegt an der verwendeten Zeichenkodierung. Die ist nicht auf allen x86 Systemen gleich. Ich gebe zu, dass es heutzutage auf den meisten gängigen Systemen funktionieren wird, aber es gibt eben keine Garantie. Wenn sich in der Zukunft etwas ändert oder man aus irgendeinem Grund auf ein exotisches System portieren muss, dann ist das ein Fehler, an den gar niemand denkt. Bis es dann kracht und womöglich noch ziemlich heftig, da irgendeine völlig unerwartete Zahl zurückkommt.

    Zum Rest mit C++ hat Nexus schon genügend gesagt 🙂

    Grüssli



  • Selbst in C++ deklariere ich oft die genutzten Variablen ganz oben in der Funktion, weil ich der Meinung bin dass es Übersichtlicher ist. Ist dann ja wohl mehr oder weniger ne frage des Geschmacks, zumindest bei den heutigen Ressourcen. ob die 40 oder 50 Byte (oder halt +255 für nen buffer oder was weiß ich) und mittendrin immer mal freigegeben werden, da der block verlassen wird oder ob das nun alles am ende der Funktion rausgeht...

    Wie gesagt, das mit dem const muss ich mir merken und es auch an meinen Prof weitergeben, dass er dies auch in seine 1 Semester C-Vorlesung mit einbauen sollte oder zumindest darauf hinweisen. Weil viele haben erst jetzt im 2. Semester zum ersten mal was von const pointer u.ä. gehört...

    Okay das mit dem Zeichensatz stimmt schon... aber wenn ich doch von stink normaler ASCII Kodierung ausgehe, dann sollte die ja immer gleich sein, weils ja ein gewisser Standard ist... Könnte halt auch die Funktion umbenennen in ASCIIToInt() um halt jegliche Zweifel zu decken.

    Und das man viele dinge in C++ eleganter lösen kann ist mir auch bewusst, wobei man auch da viel so oder auch so lösen kann, je nach Geschmack. Auch in C++ deklariere ich viele Variablen am Anfang der Funktion, halt der Übersicht halber. Solange ich da auch keine Nachteile dessen kenne werde ich das auch weiter so machen, außer jemand gibt mir einen Grund es nicht zu tun 🙂

    Für bisherige Tipps, danke ich schonmal. 🙂 Hoffe das Theadnapping stört keinen... Bin ja auch schon fertig... Jetzt noch nen Thread darüber zu erstellen wäre ja auch sinnlos. 🙂

    MFG
    Blackskyliner



  • Blackskyliner schrieb:

    Auch in C++ deklariere ich viele Variablen am Anfang der Funktion, halt der Übersicht halber. Solange ich da auch keine Nachteile dessen kenne werde ich das auch weiter so machen, außer jemand gibt mir einen Grund es nicht zu tun 🙂

    Eine Variablendeklaration geht mit deren Initialisierung einher. Bei deiner Variante werden die Variablen erst default-initialisiert, danach wird ihnen ein Wert zugewiesen. Das ist eine zusätzliche unnötige Operation.

    Desweiteren:

    int x;
    
    // 100 Zeilen Code
    
    // Hier erste Verwendung von x...
    x = createRandomNumber();
    

    Bei der Codezeile unten will der Programmierer mal überprüfen als was denn "x" jetzt genau deklariert wurde. Viel Spaß beim Scrollen 😉 (Nicht jeder verwendet eine dicke IDE, die einem beim überfahren zeigt was dahinter steckt).
    Also zählt dein Argument "Übersicht" nicht, im Gegenteil.

    Außerdem sollte man den Sichtbarkeitsbereich von Variablen (Objekten) so gering wie möglich halten.

    Es gibt sicherlich noch mehr, aber dafür bin ich jetzt zu müde 😉


  • Administrator

    Blackskyliner schrieb:

    Okay das mit dem Zeichensatz stimmt schon... aber wenn ich doch von stink normaler ASCII Kodierung ausgehe, dann sollte die ja immer gleich sein, weils ja ein gewisser Standard ist... Könnte halt auch die Funktion umbenennen in ASCIIToInt() um halt jegliche Zweifel zu decken.

    Du kannst nicht einfach davon ausgehen, es ist schlicht nicht standardisiert. Sobald du darauf setzt, hast du eine Gefahrenquelle drin. Da bringt es auch nicht, dass du die Funktion umbenennst. In einem grösseren Projekt wird das niemandem auffallen und niemand wird sich wahrscheinlich viele Gedanken über den Zeichensatz machen. Ein guter Programmierer wird ja auch die Standardmittel für die Konvertierung genommen haben und diese machen keine Probleme. Daher für den produktiven Einsatz lieber die Standardmittel verwenden.

    Zum Rest hat ja schon l'abra d'or einiges gesagt. Die Übersicht erhöht es überhaupt nicht. Was interessiert es mich am Anfang einer Funktion, was für Variablen verwendet werden? Sowas interessiert mich erst, wenn ich die Variable brauche und zu dem Zeitpunkt will ich nicht wieder nach oben schauen gehen müssen 😉

    Grüssli


Log in to reply