Hi,
nachdem ich nach längerem Suchen keine Lösung gefunden habe geht die Frage hiermit an die Profies:
Wie kann ich in c++ Zahlen wahlweise als int oder double von der Kommandozeile anfangen? Normalerweise gibt ja argc die Anzahl der Kommandozeilenargumente wieder und das array argv[] gibt die Agumente als char aus. Nun will ich jedoch Zahlen von der Kommandozeile abfragen. Meine bisherigen Versuche mittels eines:
double b; b = argv[x];
Zahlen zurückzubekommen alle gescheitert (Scheint auch eher seltsam zu sein so den Variablentyp zu ändern, aber g++ nimmt das ohne meckern hin). Gibt es da noch eine Möglichkeit an die ich nicht gedacht habe?
Dane schon mal im Voraus und noch ein schönes Wochenende an alle!
On Sun, Jan 13, 2002 at 12:51:54PM +0100, Steffen Liebergeld wrote:
Hi,
Hallo Steffen,
Wie kann ich in c++ Zahlen wahlweise als int oder double von der Kommandozeile anfangen? Normalerweise gibt ja argc die Anzahl der Kommandozeilenargumente wieder und das array argv[] gibt die Agumente als char aus. Nun will ich jedoch Zahlen von der Kommandozeile abfragen. Meine bisherigen Versuche mittels eines:
double b; b = argv[x];
double = char* dürfte wohl im besten Fall zu einem SEGFAULT führen... Du musst den char-Pointer, der im Array argv enthalten ist erst in einen int oder double Wert umrechnen => man atoi und man strtod
Ciao, Tobias
Am Sonntag, 13. Januar 2002 12:43 schrieben Sie:
On Sun, Jan 13, 2002 at 12:51:54PM +0100, Steffen Liebergeld wrote:
Hi,
Hallo Steffen,
Wie kann ich in c++ Zahlen wahlweise als int oder double von der Kommandozeile anfangen? Normalerweise gibt ja argc die Anzahl der Kommandozeilenargumente wieder und das array argv[] gibt die Agumente als char aus. Nun will ich jedoch Zahlen von der Kommandozeile abfragen. Meine bisherigen Versuche mittels eines:
double b; b = argv[x];
double = char* dürfte wohl im besten Fall zu einem SEGFAULT führen... Du musst den char-Pointer, der im Array argv enthalten ist erst in einen int oder double Wert umrechnen => man atoi und man strtod
Danke, strtod war genau das was ich suchte. Danke auch an alle anderen die Hilfelösungen geschickt haben.
Hallo,
On Sun, Jan 13, 2002 at 12:43:59PM +0100, Tobias Koenig wrote:
On Sun, Jan 13, 2002 at 12:51:54PM +0100, Steffen Liebergeld wrote:
Hi,
Hallo Steffen,
double b; b = argv[x];
double = char* dürfte wohl im besten Fall zu einem SEGFAULT führen...
Eher zu einem SIGFPE, das Bitmuster des Pointers wird in die Variable geladen und mit etwas Pech kann die FPU damit nichts anfangen...
Holger
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Sunday 13 January 2002 12:51, Steffen Liebergeld wrote:
double b; b = argv[x];
#include <stdio.h>
int main(int argc,char**argv) { //.... double b sscanf(argv[x],"%d",&b); //.... }
geht sowohl mit C als auch C++
Konrad
- -- BOFH excuse #40:
not enough memory, go get system upgrade
On Sun, Jan 13, 2002 at 01:08:36PM +0100, Konrad Rosenbaum wrote:
On Sunday 13 January 2002 12:51, Steffen Liebergeld wrote:
double b; b = argv[x];
sscanf(argv[x],"%d",&b);
[sf]scanf ist bbbb�se (wegen Ellipse, nicht typsicher ) und sollte nicht verwendet werden, wenn es Alternativen gibt (siehe andere Antworten).
Gru�, Eric
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Sunday 13 January 2002 16:40, Eric Schaefer wrote:
On Sun, Jan 13, 2002 at 01:08:36PM +0100, Konrad Rosenbaum wrote:
On Sunday 13 January 2002 12:51, Steffen Liebergeld wrote:
double b; b = argv[x];
sscanf(argv[x],"%d",&b);
[sf]scanf ist bbbböse (wegen Ellipse, nicht typsicher ) und sollte nicht verwendet werden, wenn es Alternativen gibt (siehe andere Antworten).
Hallo Eric,
Angriffe auf scanf nutzen normalerweise dynamische Formatstrings oder Stringargumente, die zu kurz geraten sind.
Dir als grossem C- und Security-Experten haette etwas anderes auffallen muessen: ich habe das falsche %-Statement benutzt, es haette %lf sein muessen.
Solange man mit scanf keine Strings einliest (%s) und keine dynamischen Formatstrings benutzt oder wie oben das falsche Statement benutzt ist es absolut sicher. Und selbst dann kannst Du durch gruendliche Code-Pruefung und entsprechende Tests die Sicherheit hochschrauben, man muss halt nur wissen, wonach man zu suchen hat.
GNU C sagt einem uebrigens, dass es das falsche Statement ist: ich hatte den Code noch nicht getestet und es deswegen nicht gleich mitbekommen.
Solange man bestimmte Regeln beachtet sind auch Ellipsen, Pointer-Arithmetik, Puffer und einige andere potentielle Sicherheitsluecken ungefaehrlich. C bringt es nun einmal mit sich, dass Du aufpassen musst, was Du tust.
Zum Thema Alternativen: die sind meistens genauso anfaellig gegen Angriffe, wie scanf. Die Fehler werden nur von anderen gemacht.
Wenn Du eine sicherere Umgebung haben willst, in der Du kaum Fehler machen kannst, dann nimm Skriptsprachen. Es gibt einige dutzend davon, such Dir eine aus.
Uebrigens: char buf[1024]; 1: snprintf(buf,1023,"%s\n",somestring) 2: cin>>buf;
welches der beiden Statements ist Deiner Meinung nach fuer einen Angriff gefaehrdet? Nr. 1 mit der ach so boesen Ellipse oder 2 mit dem voellig harmlosen >>-Operator?
Das naechste Mal bitte nachdenken, bevor Du schreist.
SCNR, Konrad
- -- BOFH excuse #106:
The electrician didn't know what the yellow cable was so he yanked the ethernet out.
Am Sonntag, dem 13. Januar 2002 um 17:48:32, schrieb Konrad Rosenbaum:
Das naechste Mal bitte nachdenken, bevor Du schreist.
Eric hat vollkommen recht, was die Typsicherheit betrifft. Außerdem war explizit nach einer C++-Lösung gefragt.
char buf[1024]; 1: snprintf(buf,1023,"%s\n",somestring) 2: cin>>buf;
Wer den Stroustrup gelesen hat, wird beides nicht machen. BTW, deine Beispiele haben rein gar nicht mit der ursprünglichen Frage zu tun - wie man eine char*-Repräsentation einer Gleitkommazahl nach double konvertiert.
Torsten
On Sun, Jan 13, 2002 at 05:48:32PM +0100, Konrad Rosenbaum wrote:
sscanf(argv[x],"%d",&b);
[sf]scanf ist bbbb�se (wegen Ellipse, nicht typsicher ) und sollte nicht verwendet werden, wenn es Alternativen gibt (siehe andere Antworten).
Angriffe auf scanf nutzen normalerweise dynamische Formatstrings oder Stringargumente, die zu kurz geraten sind.
Ach Konrad, k�mpfst Du mal wieder gegen Windm�hlen? Wo schrieb ich was zu "Angriffen"? Wei�t Du was "typsicher" bedeutet? Es ging mir nur darum, da� Funktionen wie, strtof(3) besser darauf achten, was Ihnen da so �bergeben wird, da alle Argumente typisiert sind, was man von einer Ellipse nicht gerade sagen kann. Wenn Du scanf einen Schei�string �bergibst bekommst Du Schei�e zur�ck (Sorry), w�hrend strtof Bescheid sagt, wenn was im Argen ist.
Was Du genau dem scanf da �bergibst, hab ich mir gar nicht angesehen und h�tte auch das Manual zu Rate ziehen m�ssen, da ich NIE scanf benutze, aus genannten Gr�nden. Deshalb ist
Dir als grossem C- und Security-Experten haette etwas anderes auffallen muessen: ich habe das falsche %-Statement benutzt, es haette %lf sein muessen.
auch hinf�llig.
Solange man bestimmte Regeln beachtet sind auch Ellipsen, Pointer-Arithmetik, Puffer und einige andere potentielle Sicherheitsluecken ungefaehrlich. C bringt es nun einmal mit sich, dass Du aufpassen musst, was Du tust.
Kein Einwand, ich sprach gar nicht �ber Sicherheit (Buffer-Overflow & Co.)
Wenn Du eine sicherere Umgebung haben willst, in der Du kaum Fehler machen kannst, dann nimm Skriptsprachen. Es gibt einige dutzend davon, such Dir eine aus.
Nun ja, da hab ich vielleicht kein BOs, aber daf�r kann ich mir die Typen bei den meisten Skiptsprachen gleich in die Haare schmieren... Kompromiss? -> Ada? (�h, ich meine JEHOVA)
Uebrigens: char buf[1024]; 1: snprintf(buf,1023,"%s\n",somestring) 2: cin>>buf;
welches der beiden Statements ist Deiner Meinung nach fuer einen Angriff gefaehrdet? Nr. 1 mit der ach so boesen Ellipse oder 2 mit dem voellig harmlosen >>-Operator?
Definier "Gef�hrdung". BOs: (1) unproblematisch [ohne weiter dr�ber nachzudenken], (2) keine Ahnung sonst: (1) int somestring=SOMENUMBER; (2) k.A.
Die Antworten zu (2) resultieren aus dem Unverst�ndnis f�r die Notwendigkeit der objektorientierten Darstellung von I/O durch Streamklassen und dem daraus entstanden Ignorieren dergleichen.
Das naechste Mal bitte nachdenken, bevor Du schreist.
Wer schreit denn?
Gru�, Eric
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Monday 14 January 2002 19:05, Eric Schaefer wrote:
Ach Konrad, kämpfst Du mal wieder gegen Windmühlen?
nein, gegen Halbwissen(*).
(*)manchmal auch mein eigenes. ;-)
Wo schrieb ich was zu "Angriffen"? Weißt Du was "typsicher" bedeutet? Es ging mir nur darum, daß Funktionen wie, strtof(3) besser darauf achten, was Ihnen da so übergeben wird, da alle Argumente typisiert sind, was man von einer Ellipse nicht gerade sagen kann. Wenn Du scanf einen Scheißstring übergibst bekommst Du Scheiße zurück (Sorry), während strtof Bescheid sagt, wenn was im Argen ist.
dazu hat GNU C zusaetzliche Regeln, die ihm sagen, was die %-Argumente bedeuten. Schonmal ueber eine Warnung, wie die hier gewundert?: xyz.c line abc: Warning %lf used, but char* given
Im Uebrigen ist C keine Anfaengersprache und auch nicht fuer Featuritisten geeignet. Wenn Du eine einigermassen saubere, moderne und typsichere Sprache willst nimm Java(**), wenn Du eine fuer Experten geeignete schnelle Sprache willst C/C++, fuer echte Objektorientierung SmallTalk. Sorry, Kompromisse gibts keine (mir sind jedenfalls noch keine guten ueber den Weg gelaufen).
(**)GCC 3.x kann uebrigens auch Java in native Code uebersetzen. Ist sicherlich eine Ueberlegung wert.
Konrad
- -- BOFH excuse #264:
Your modem doesn't speak English.
On Tue, Jan 15, 2002 at 07:20:07AM +0100, Konrad Rosenbaum wrote:
On Monday 14 January 2002 19:05, Eric Schaefer wrote:
Wo schrieb ich was zu "Angriffen"? Wei�t Du was "typsicher" bedeutet? Es ging mir nur darum, da� Funktionen wie, strtof(3) besser darauf achten, was Ihnen da so �bergeben wird, da alle Argumente typisiert sind, was man von einer Ellipse nicht gerade sagen kann. Wenn Du scanf einen Schei�string �bergibst bekommst Du Schei�e zur�ck (Sorry), w�hrend strtof Bescheid sagt, wenn was im Argen ist.
dazu hat GNU C zusaetzliche Regeln, die ihm sagen, was die %-Argumente bedeuten. Schonmal ueber eine Warnung, wie die hier gewundert?: xyz.c line abc: Warning %lf used, but char* given
Nein, hab ich nicht, da ich kein scanf verwende. Abgesehen davon ist das aber nicht portabel (von Compiler zu Compiler). Au�erdem ist scanf bloat wenn es nur um die Konvertierung eines einzigen Wertes geht, schlie�lich mu� der Formatstring interpretiert werden...
Im Uebrigen ist C keine Anfaengersprache und auch nicht fuer Featuritisten geeignet. Wenn Du eine einigermassen saubere, moderne und typsichere Sprache willst nimm Java(**), wenn Du eine fuer Experten geeignete schnelle Sprache willst C/C++, fuer echte Objektorientierung SmallTalk. Sorry, Kompromisse gibts keine (mir sind jedenfalls noch keine guten ueber den Weg gelaufen).
** Er hat JEHOVA gesagt!!! (ich nehm einen gro�en spitzen Stein und 5 kleine abgerundete)
(**)GCC 3.x kann uebrigens auch Java in native Code uebersetzen. Ist sicherlich eine Ueberlegung wert.
Ist das dann schneller als Java-Bytecode? Wieviel langsamer als nativer C-Code?
Gru�, Eric
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Tuesday 15 January 2002 16:57, Eric Schaefer wrote:
On Tue, Jan 15, 2002 at 07:20:07AM +0100, Konrad Rosenbaum wrote:
dazu hat GNU C zusaetzliche Regeln, die ihm sagen, was die %-Argumente bedeuten. Schonmal ueber eine Warnung, wie die hier gewundert?: xyz.c line abc: Warning %lf used, but char* given
Nein, hab ich nicht, da ich kein scanf verwende. Abgesehen davon ist das aber nicht portabel (von Compiler zu Compiler).
dafuer ist der GNU C Compiler portabel ;-)
Außerdem ist scanf bloat wenn es nur um die Konvertierung eines einzigen Wertes geht, schließlich muß der Formatstring interpretiert werden...
jepp.
Im Uebrigen ist C keine Anfaengersprache und auch nicht fuer Featuritisten geeignet. Wenn Du eine einigermassen saubere, moderne und typsichere Sprache willst nimm Java(**), wenn Du eine fuer Experten geeignete schnelle Sprache willst C/C++, fuer echte Objektorientierung SmallTalk. Sorry, Kompromisse gibts keine (mir sind jedenfalls noch keine guten ueber den Weg gelaufen).
** Er hat JEHOVA gesagt!!! (ich nehm einen großen spitzen Stein und 5 kleine abgerundete)
Jehova! Jehova!! ...
(**)GCC 3.x kann uebrigens auch Java in native Code uebersetzen. Ist sicherlich eine Ueberlegung wert.
Ist das dann schneller als Java-Bytecode? Wieviel langsamer als nativer C-Code?
Ich kenne nur die Angaben der Entwickler, ich bin noch nicht dazu gekommen es selbst zu pruefen.
Vergleich Bytecode: der Startup-Zyklus verkuerzt sich von 30s auf 5s (das Laden der VM entfaellt). Der Code ist zwischen Faktor 5 und 60 schneller (je nachdem mit welcher VM du vergleichst, wie gut der Code optimierbar ist und ob er in der vergleichenden VM schon durch den JIT lief).
Vergleich C-Code: ich glaub das war aehnlich schnell bis Faktor 2 langsamer. Da dieses Frontend fuer GCC aber noch nicht lange existiert ist es auch noch nicht so gut optimiert, da kann also noch einiges rausgeholt werden. Auf jeden Fall wird empfohlen GCC auf den Source loszulassen und nicht auf den Bytecode, da ersterer besser optimierbar ist.
Konrad
- -- If some day we are defeated, well, war has its fortunes, good and bad. -- Commander Kor, "Errand of Mercy", stardate 3201.7
On Tue, Jan 15, 2002 at 04:57:43PM +0100, Eric Schaefer wrote:
On Tue, Jan 15, 2002 at 07:20:07AM +0100, Konrad Rosenbaum wrote:
(**)GCC 3.x kann uebrigens auch Java in native Code uebersetzen. Ist sicherlich eine Ueberlegung wert.
Ist das dann schneller als Java-Bytecode? Wieviel langsamer als nativer C-Code?
Das dumme an Java -> native code ist, daß man damit kaum den gesamten Java-Standard abdecken kann. Sowas wie nachladbare Klassen fällt dann sicher unter Tisch, oder?
Reinhard
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Tuesday 15 January 2002 20:38, Reinhard Foerster wrote:
On Tue, Jan 15, 2002 at 04:57:43PM +0100, Eric Schaefer wrote:
On Tue, Jan 15, 2002 at 07:20:07AM +0100, Konrad Rosenbaum wrote:
(**)GCC 3.x kann uebrigens auch Java in native Code uebersetzen. Ist sicherlich eine Ueberlegung wert.
Ist das dann schneller als Java-Bytecode? Wieviel langsamer als nativer C-Code?
Das dumme an Java -> native code ist, daß man damit kaum den gesamten Java-Standard abdecken kann. Sowas wie nachladbare Klassen fällt dann sicher unter Tisch, oder?
lustigerweise nicht. GCC Java hat (logischerweise) eine eigene libgj.so (oder wie die auch immer hiess) und die enthaelt einen runtime-loader. Man kann also durchaus die recht interessante Situation erzeugen, dass compilierter Code friedlich neben Bytecode im Speicher rumluemmelt und beide zusammenarbeiten. Jedenfalls, wenn man den Angaben der GCC Entwickler glauben darf.
Konrad
- -- BOFH excuse #308:
CD-ROM server needs recalibration
Hallo,
On Sunday, 13. January 2002 12:51, Steffen Liebergeld wrote:
double b; b = argv[x];
Das ist eine Zuweisung vom Type (double) = (char *), das kann nicht funktionieren.
Zahlen zurückzubekommen alle gescheitert (Scheint auch eher seltsam zu sein so den Variablentyp zu ändern, aber g++ nimmt das ohne meckern hin). Gibt es da noch eine Möglichkeit an die ich nicht gedacht habe?
Also meiner meckert da (2.95.4 bzw. 3.0.3), mit -Wall erst recht. Du mußt eine Konvertierungsfunktion verwenden, die den String interpretiert und ihn in eine Zahl umwandelt. Der Computer weiß ja nichts von unserem Zahlensystem, z.B. daß ein Punkt (bzw. Komma) die Dezimaltrennung ist oder ein Minus ein Vorzeichen bedeutet.
Beispiel:
#include <iostream> #include <cstdlib>
int main (int argc, char **argv) { if (argc == 2) { double b = atof(argv[1]); cout << "Argument: " << b << endl; } return 0; }
Alternativ kannst du auch Sprachen verwenden die das mit der Typisierung anders handhaben, z.B. Skriptsprachen (Perl/Python/Ruby/...), aber in C/C++ muß man entweder "casten" (bei Typen wie int, float, double, char), oder Konvertierungsfunktionen verwenden.
Josef Spillner
Am Sonntag, dem 13. Januar 2002 um 12:51:54, schrieb Steffen Liebergeld:
double b; b = argv[x];
Mit 'c++ -Wall' sollte der Compiler warnen.
Folgendes müsste funktionieren (ungetestet):
std::istringstream argx(argv[x]); double b; argx >> b; if (!argx) { std::cerr << "Konvertierung fehlgeschlagen!\n"; throw argv[x]; }
Torsten
lug-dd@mailman.schlittermann.de