2016-08-15 2 views
1

Ich bin ein bisschen verrückt versuchen, eine sehr einfache Operation-Funktion in C als Anfänger, aber es scheint alles, was ich versuche fehlgeschlagen, obwohl es funktionieren soll.Der Versuch, einfache do_operation-Funktion in C

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 

int  calcul(int nb1, int nb2, char *av) 
{ 
     int nb = 0; 
     if (av[2] == '*') 
       nb = nb1 * nb2; 
     if (av[2] == '%') 
       nb = nb1 % nb2; 
     if (av[2] == '/') 
       nb = nb1/nb2; 
     if (av[2] == '+') 
       nb = nb1 + nb2; 
     if (av[2] == '-') 
       nb = nb1 - nb2; 
     return (nb); 
} 

int  atoi(); 

int  main(int ac, char **av) 
{ 
     printf("%s", av[2]); 
     if (ac == 4) 
       printf("%d", calcul(atoi(av[1]), atoi(av[3]), av[2])); 
     return (0); 
} 

Es ist wie bei bald als das zweite Argument scheint, die der Betreiber ist, geht durch die calcul Funktion, den tatsächlichen Charakter in verändern entweder es ist ASCII-Wert oder sonst etwas, so dass in dem Zustand nicht richtig erkannt wird .

Ich habe versucht, viele Möglichkeiten zu geigen und andere Schnipsel nachschlagen, aber das ist genau das, was sie taten und wie es funktionieren soll (auch wenn ich die printf entferne), was mache ich falsch?

EDIT Tut mir leid, ich ändere absichtlich die Anzahl der Argumente, um einen segfault für etwas anderes zu bekommen, hier ist die "richtige" Funktion, die ich testen, für die ich das Problem bekomme.

Auch die Art, wie ich diese Funktion bin mit ist durch einen einfachen zusammengestellt prog unter diesem Format in der Schale ausgeführt wird:

./a.out 2 * 3 

GELöST Wie @ Mike darauf hingewiesen, wenn die calculate Funktion Eingabe av [2 ] was nun der Operator ist, wurde als erstes und einziges Zeichenargument betrachtet, daher sollte es mit av [0] identifiziert werden. Was ist ein wenig verwirrend/schwierig.

+0

Wenn Sie eine Shell verwenden, interpretiert sie Ihren Operator möglicherweise als Muster und ersetzt sie durch eine Erweiterung, wenn Sie sie in Ihrem Programm haben – jxh

+0

Wie genau Soll dieses Programm aufgerufen werden? – dbush

+0

Es scheint auch, dass Sie über das 'char ** av'-Array hinaus zugreifen. Wenn' ac == 4', dann sind die einzigen gültigen Indizes für 'av' 0 bis 3. – yano

Antwort

2

Sie haben Ihre Indizierung falsch. Ich habe den Code ein wenig geändert, vorausgesetzt, Sie wollten das Operatorzeichen drucken, um sicherzustellen, dass es funktioniert.

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 

int  calcul(int nb1, int nb2, char *av) 
{ 
     int nb = 0; 
     printf("%c\n", av[0]); 
     if (av[0] == '*') 
       nb = nb1 * nb2; 
     if (av[0] == '%') 
       nb = nb1 % nb2; 
     if (av[0] == '/') 
       nb = nb1/nb2; 
     if (av[0] == '+') 
       nb = nb1 + nb2; 
     if (av[0] == '-') 
       nb = nb1 - nb2; 
     return (nb); 
} 

int  main(int ac, char **av) 
{ 
     printf("%s\n", av[2]); 
     if (ac == 4) 
       printf("%d\n", calcul(atoi(av[1]), atoi(av[3]), av[2])); 
     return (0); 
} 

Hinweis in Ihrem calcul funciton Sie av[2] fordern, die die versuchen, den dritten Index eines Strings nur Ihren Operator enthält, zu erhalten, die NULL ist.

ETA:

Auch eine Notiz auf dem * Operator. Um es zum Laufen zu bringen, müssen Sie es mit einem Escape-Zeichen \ aufrufen.

ETA2:

den Code geändert, um die Änderungen in der Antwort auf übereinstimmen, so kann es mit aufgerufen werden:

Gerade
./a 3 + 4 
./a 3 '*' 9 
+1

Sie können auch einfache Anführungszeichen verwenden: um den Stern beim Aufruf des Programms 'berechnen '*'' 5 4 – FredK

+0

Ich kompiliere und läuft das Programm unter diesem Formular: ./a.out 2 * 3 So sollte der Operator die av [2] sein, aber es liest es nicht. – yazze

+0

@yazze Einfache Lösung. Ändere die Zeile calcul (atoi (av [3]), atoi (av [2]), av [1])) zurück zu calcul (atoi (av [1]), atoi (av [3]), av [ 2])) mit dem gleichen Code in der Antwort und ändern Sie die printf-Anweisungen entsprechend um 'av [2]' zu zeigen. Behalten Sie jedoch die Anweisung 'av [0]' wie in den if-Anweisungen bei. – Mike

0

ein in den Kommentaren zu Ihrer Frage folgen ...

Argumente werden an c Programme als ein Array von Zeichenfolgen übergeben; das ist eine Liste von Zeichenfolgen. Eine c Zeichenfolge ist eine Liste von Zeichen, daher ist eine Liste von Zeichenfolgen eine 2-d-Matrix oder eine Matrix von Zeichen. Jede Zeichenfolge hat einen Index.Jede char innerhalb einer Zeichenkette hat ein Index Sie können es als ein Gitter visualisieren:

      Index of char in string 
         _|_0_|_1_|_2_|_3_|_4_|_5_| ... etc 
         0|___|___|___|___|___|___|___ 
         1|___|___|___|___|___|___|___ 
         2|___|___|___|___|___|___|___ 
Index of string in list 3|___|___|___|___|___|___|___ 
         4|___|___|___|___|___|___|___ 
         5|___|___|___|___|___|___|___ 
         ... etc 

Also, wenn Sie nennen Ihr Programm ./a.out 3 '*' 9, char** av wird 4 Zeichenfolgen enthalten:

av[0] = "a.out" 
av[1] = "3" 
av[2] = "*" 
av[3] = "9" 

Natürlich c Saiten NULL-terminiert, so dass Sie in der Rasteransicht sehen würden

Das erste Zeichen jeder Zeichenfolge beginnt bei Index 0; So zum Beispiel, string 0, char 0 ist 'a', oder

av[0][0] = 'a' 
av[1][0] = '3' 
av[2][0] = '*' 
av[3][0] = '9' 

wenn Sie av[2] an Ihre Funktion übergeben, Sie sind ein char* auf das gesamte 3.-string Argument übergeben (die in diesem Fall nur aus 1 char, das * Zeichen). Daher überprüft Mike in der calcul Funktion korrekt die erste char der Zeichenfolge, wo sich der Operator befindet. In der calcul-Funktion enthält av[1] das NULL-Byte \0 des Zeichenfolge-Terminators und av[2] und höher sind undefinierte Indizes. Ich würde empfehlen, den Namen des av Arguments in der calcul Funktion zu etwas anderem zu ändern, also verwechseln Sie es nicht mit dem av Argument vom Haupt.

Denken Sie daran, in diesem Fall ist char** av eine Liste von Zeichenfolgen (wobei jeder Index 0, 1, 2 usw. eine Zeichenfolge in dieser Liste adressiert und char* av eine einzelne Zeichenfolge ist (wobei jeder Index 0, 1, 2, etc, adressiert ein Zeichen in dieser Zeichenkette.)