简体   繁体   中英

Command line arguments in C- weird output

So I've written a code for a simple reverse Polish calculator that works only for positive numbers using command line arguments. It stores the numbers in a stack. The functions for push and pop are in a separate source file.
I've also written another program, to check the control flow of my previous program.
Here's the first program:

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
void push(double);
double pop(void);
int main(int argc, char *argv[])
{
    int c;
    double op2;
    while(--argc>0 && (c=(*++argv)[0]))
        if(isdigit(c))
            push(atof(argv[0]));

        else if(c=='+')
            push(pop()+pop()); 

        else if(c=='-')
        {
            op2=pop();
            push(pop()-op2); 
        }

        else if(c=='*')
            push(pop() * pop()); 

        else
        {
            op2=pop();
            push(pop()/op2); 
        }

    printf("\n%f\n", pop());   
    return 0;
} 

After I run this program, all the operators work, except '*'. For instance, if my input is ' ./pcalc 2 3 * ', then this is the output I get:
error: stack emptyerror: stack emptyerror: stack emptyerror: stack empty -nan

If I interchange the conditions in the while loop, like this
while((c=(*++argv)[0]) && --argc>0)
then I get a 'segmentation fault (core dumped)' message for all operators.

To know the control flow of my program, I changed a part of the code to this:

while(--argc>0 && (c=(*++argv)[0]))
    if(isdigit(c))
        printf("\nentry1\n");

    else if(c=='+')
        printf("\nentry2\n");

    else if(c=='-')
        printf("\nentry3\n");    

    else if(c=='*')
        printf("\nentry4\n");

    else
        printf("\nentry5\n");  

The rest of the program was similar to the first one. On giving input as ' ./pcalc 2 3 * ', I get this output:

entry1

entry1

entry5

entry5

entry5

entry5

entry5
error: stack empty  
0.000000  

This means that control didn't go to the case for asterisk, and instead went to the else part.
When I interchange the conditions of the while loop, the output I get is similar as above( for all the operators, it shows the control flow, and for '*', it shows the same error as above), except, that it doesn't show the stack empty error for any operator, and shows instead a segmentation fault (core dumped) message.

So this is what I want to ask:
1) My first program worked for all operators, except '*'. What could be the reason? Why did the control go to the else part?

2) After interchanging the conditions, what memory was I accessing that I didn't have permission to? If it was NULL, then shouldn't that break the while loop anyway and proceed?

PS. This is my first question, so if there are any errors in my writing style, or if the question is too long, kindly let me know! We learn from our mistakes :)
Also, my compiler-GCC, OS-Ubuntu.

User xing is absolutely right.
To expand on it, the && operator is evaluated from left to right. If the left condition is not valid, then the right condition will not be evaluated as the return value is already known to be 0 (false).
Running ./pcalc 2 3 * will be expanded to ./pcalc 2 3 <all the files/directories in current working directory> so it will never push an operator on the operators' stack.

  • while(--argc>0 && (c=(*++argv)[0])) will first check if it is still within the arguments array before extracting the first element.
  • while((c=(*++argv)[0]) && --argc>0) will first try to extract a value, then check if it is still within the boundaries of the array. If not, well it has already segfaulted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM