String mit Integer vergleichen
-
Hallo liebes Forum,
ich würde gerne einen String, bzw. die einzelnen Zeichen mit einer Zahl vergleichen.
Mein Ziel:
Parameteringaben (zahlen von 0-8) auf der Konsole, welche in der char *argv[] gespeichert sind, sollen nun bitweise abgespeichert werden.Mein Code:
int biteingaben[9] = {0,0,0,0,0,0,0,0,0}; //Hier sollen die Zahlen von 1-9 jeweils als "1" an der jeweiligen stelle gespeichert werden, wenn eine Zahl gefunden wurde. Beispiel: zahl 1 und 3, dann sieht das Arra so aus: {0,1,0,1,0,0,0,0,0} void pruefe_eingaben(char**argv) { int i, j; for(i=0;i<9;i++) for(j=0;j<9;j++) if(argv[1][i] == 'j') biteingaben[j] == 1; } int main(int argc, char *argv[]) { int i; pruefe_eingaben(argv); for(i=0;i< 9;i++) printf("%d\n",biteingaben[i]); system("PAUSE"); return 0; }
Leider wird nichts in biteingaben geschrieben, hat jemand eine Idee?
-
Was macht denn Zeile 7? Netter Vergleich. ^^
-
EDIT: Zeile 8 sollte natürlich so lauten:
biteingaben[j] = 1;
und ja, in Zeile 7 vergleiche ich den zweiten übergabewert aus der konsole mit der zahl, an der stelle in dr Ascii-Tabelle.
Warum das nicht funktioniert, weiß ich nicht.In der Konsole würde ich meinen Parameter so durchgeben:
programm.exe 123
und diese 3 zahlen sollen nun bitweise gespeichert werden. tuts aber leider nicht.
-
Gib doch mal
programm.exe jxjyj
ein.
-
Das 'j' ist nicht das Zeichen, das den Ziffernwert der Variablen j hat.
'j' ist die kleine Ausführung des 10 Buchstaben des lateinischen Alphabets.
Du wolltest (j+'0') haben.Allerdings hast du noch ein paar andere Macken:
Du prüfst aber nicht 1 bis 9 sondern 0 bis 8.
Du prüfst auch an Stellen, die gar nicht mehr zu argv [1] gehören. Dein 123 hat nur 3 Stellen, du schaust aber bis Stelle 9.
Du prüfst nicht, ob es überhaupt ein argv[1] gibt.void pruefe_eingaben(char**argv) { char *p = argv[1]; // wäre argv in Funktionskopf besser definiert, wäre das auch überflüssig for(;*p;p++) if (isdigit(*p) && (*p != '9')) // isdigit aus ctype.h evtl meinst du aber statt '9' die '0' biteingaben[(*p)-'0']++; // statt ++ darfst du auch =1 schreiben }
Du kannst auch
void pruefe_eingaben(const char *p)
machen und dann mit
pruefe_eingaben(argv[1]) aufrufen.
-
Jo das mit den makcen habe ich auch gerade gemerkt, danke
Die for-schleife deines Codes verstehe ich leider nicht so ganz.
Ich sehe das Abbruchkriterium und verstehe das hochzählen des Pointers leider nicht.
wird das mit hochzählen des pointers so in etwa aussehen:*p[0]
p++
*p[1]
...
?Wenn du mir das beides noch erklären könntest, wäre das echt super.
Bisher habe ich nur mit for(i = 0; i< ...; i++) gearbeitet oder mit hile schleifen, was mich an dein konstrukt schon sehr erinnert.
-
for und while-Schleifen sind eh nur andere Schreibweisen.
for( start; test; next) Anweisung;
gegen
start; while(test) { Anweisung; next; }
Die Schleife läuft solange der test ungleich 0 ist.
*p ist eine Kurzschreibweise für*p != '\0'
.
Da das Stringendezeichen aber auch 0 ist, läuft die Schleife solange sie auf Zeichen trifft.Das p++ zählt den Zeiger eine Position weiter.
Von argv[1][0] auf argv[1][1].
-
Jo vielen dank für die erläuterung.
Eine Schlussfrage beschäftigt mich aber doch noch:
Gibt es einen besonderen grund, warum du hier mit dem hochzählendne pointer gearbeitet hast?
Hat das vorteile oder ist es einfach nur dein Programmierstil?man hätte ja auch meinen code nehmen können (modifiziert, dass es geht natürlich) und dann als array mit argv[][] abfagen können.
-
Mit dem Zeiger brauchst du nur eine Variable, es entfällt einmal dereferenziern und die Offsetberechnung entfällt.
Wenn der Compiler deinen Code nicht optimiert, ist meiner schneller.Ich würde aber auch alle Ziffern (0-9) erkennen lassen und nicht argv übergeben sondern argv[1] (Der Funktionskopf muss dann allerdings geändert werden).
Zudem ist eine globale Variable nicht so gut.int biteingaben[10] = {0}; // Ein Element reicht, dann werden die anderen automatisch auf 0 gesetzt. ... int* pruefe_eingaben(int biteingaben[], const char *p) { // Das const ist eine Zusicherung an den Aufrufer, das an dem Inhalt, auf den p zeigt, nichts geändert wird for(;*p;p++) if (isdigit(*p)) // isdigit aus ctype.h biteingaben[(*p)-'0']++; // statt ++ darfst du auch =1 schreiben return biteingaben; } int main(int argc, char *argv[]) { int i; pruefe_eingaben(biteingaben, argv[1]); ... }
-
Damit ich das richtig verstehe:
Den pointer den ich dort setzte ersetz die Derefenzierung auf das argv oder?
Würde ja bedueten, wenn ich Argv weiter benutzen würde, würde es heißen, dass man mehr zeitaufwand hat oder?Und die offsetberechnung findet nicht statt, weil man den zieger einfach gegen null laufen lässt?
Du sagtest auch noch, eine Globale variable ist nicht so gut, hast sie aber auch selbst noch verwendet, wieso denn?
-
Craiten.t schrieb:
Damit ich das richtig verstehe:
Den pointer den ich dort setzte ersetz die Derefenzierung auf das argv oder?
Würde ja bedueten, wenn ich Argv weiter benutzen würde, würde es heißen, dass man mehr zeitaufwand hat oder?argv ist ja ein Doppelzeiger.
Du hast ein Array aus Zeigern auf char. argv zeigt auf das Array. Mit dem ersten Index suchst du dir den Zeiger auf den String aus. Du mußt also erstmal argv[1] ermitteln.
Und dann noch den Index i (von argv[1][i]) daraufrechnen um an das einzelne Zeichen zu kommen.Craiten.t schrieb:
Und die offsetberechnung findet nicht statt, weil man den zieger einfach gegen null laufen lässt?
Nicht ganz.
Du zählst den Zeiger einfach weiter. Wenn das Element auf das der dann Zeigt 0 enthält, wird die Schleife abgebrochen.Craiten.t schrieb:
Du sagtest auch noch, eine Globale variable ist nicht so gut, hast sie aber auch selbst noch verwendet, wieso denn?
Für die Funktion
pruefe_eingaben
macht das jetzt aber keinen Unterschied, obbiteingaben
lokal oder global ist.
Das funktioniert in beiden Fällen.Formuliere ich jetzt mal anders:
Globale Variable statt Funktionsparameter sind schlecht.