Thread: * Character in

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    12

    * Character in

    I am reading the holy C programming book by K&R, and I took on Exercise 5-10. It asked to write a program expr which evaluated a postfix expression, such as

    expr 3 4 *

    and I made my output look like,

    = 12

    The program I wrote works just fine, except for one thing: It will not accept the * character. All other characters work, except for that one, and I can't understand why.

    Here is my full program:

    Code:
    #include <stdio.h>
    
    int ati(char *s);
    void push(int a);
    int pop(void);
    
    main(int ac, char *arg[]){
       int status = 0;
       while(--ac>0){
          int s;
          switch(**++arg){
             case '0': case '1': case '2': case '3': case '4':
             case '5': case '6': case '7': case '8': case '9':
                push(ati(*arg));
                continue;
             case '+':
                push(pop()+pop());
                continue;
             case '*':      /*   <-- trouble maker  any other characters work, such as # and x  */
                push(pop() * pop());
                continue;
             case '-':
                s = pop();
                push(pop()-s);
                continue;
             case '/':
                s = pop();
                push(pop()/s);
                continue;
             default:
                printf("Unrecognized Figure!\n");
                status = 1;
                break;
          }
       }
       printf(!status ? " = %d\n" : "",pop());
    }
    
    int ati(char *s){         /* Just a simple string to integer converter I wrote, despite the fact there is one already  */
       int o = 0;
       while(*s!='\0'){
          o = 10*o + *s++ - '0';
       }
       return o;
    }
    
    int stack[255];
    int p=0;
    
    void push(int a){
       stack[p++] = a;
    }
    
    int pop(void){
       return stack[--p];
    }
    The case '*': is the trouble maker. I have replaced it with an x, and then it works fine. Does anyone know why the asterisk produces weird results?
    (In case it matters, I have Windows Vista)
    Last edited by Jonnyb42; 01-11-2010 at 11:53 PM.

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Did the idea that * is also used to indicate a pointer in C, get considered?

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    12
    Yes, but when surrounded in single quotes '*' indicates it as a character right? I have tried backslashing the asterisk, and it said that is not an escape sequence. Also, in K&R, they write a program to calculate postfix expressions earlier in the text and they use '*' just as well.

  4. #4
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    The problem is not in your program but in the way the shell is interpreting your command line argument. * is a metacharacter for filename expansion. (I'm assuming the Windows shell acts the same as my Bash shell in this regard.)

    Leave the program as you have it in post #1. Run it using (assuming your executable is "postfix.exe"):

    Code:
    postfix.exe 3 4 '*'
    or
    Code:
    postfix.exe 3 4 \*

  5. #5
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    More than likely the asterisk is being interpreted by your shell.
    I.e., call it like so:
    Code:
    expr 3 4 \*
    That depends on your shell though.

    Also some tips:
    * main() returns int, so make it so. i.e. "int main(int argc, char * argv[])"
    * The main loop in "main()" is rather ... at least add some informative error checking.
    Code:
    int main(int ac, char *arg[])
    {
       int status = 0;
       char ch = 0;
       while(--ac>0){
          int s;
          ch = **++arg;
          switch(ch)
          {
             case '0': case '1': case '2': case '3': case '4':
             case '5': case '6': case '7': case '8': case '9':
                push(ati(*arg));
                continue;
             case '+':
                push(pop()+pop());
                continue;
             case '*':      /*   <-- trouble maker  any other characters work, such as # and x  */
                push(pop() * pop());
                continue;
             case '-':
                s = pop();
                push(pop()-s);
                continue;
             case '/':
                s = pop();
                push(pop()/s);
                continue;
             default:
                printf("Unrecognized Figure! %c\n", ch);
                status = 1;
                break;
          }
       }
       printf(!status ? " = %d\n" : "",pop());
    
       return 0;
    }

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    12

    Leave the program as you have it in post #1. Run it using (assuming your executable is "postfix.exe"):

    Code:
    postfix.exe 3 4 '*'
    or
    Code:
    postfix.exe 3 4 \*
    Hmm, I tried both, and the first repeated "Unrecognized Figure!\n" 36 times, (my default case) and the second time simply said Unrecognized Figure.

  7. #7
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    OK you got me to boot Windows (2000) for a change. Apparently in Windows, to prevent the metacharacter expansion you have to use double quotes, so try:

    Code:
    postfix.exe 3 4 "*"

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    12
    Quote Originally Posted by R.Stiltskin View Post
    OK you got me to boot Windows (2000) for a change. Apparently in Windows, to prevent the metacharacter expansion you have to use double quotes, so try:

    Code:
    postfix.exe 3 4 "*"
    Sorry Stiltskin, but it still doesn't work for me

  9. #9
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    You also have a bug, print out the current argument in the default switch case (like the code I posted above).

  10. #10
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Don't know what to tell you. It works for me in Linux, Windows 2000 and Windows XP (using '*' in Linux and "*" in both Windows versions.

    What do you get when you print out the value of ch as zacs7 suggested?

  11. #11
    Registered User
    Join Date
    May 2009
    Posts
    12
    Ok so I changed it to debug as zacs7 suggested, and the output of:

    postc 3 4 * (<-- my filename is postc.exe)

    is:

    Unrecognized Figure! b
    Unrecognized Figure! b
    Unrecognized Figure! e
    Unrecognized Figure! e
    Unrecognized Figure! p
    Unrecognized Figure! p
    Unrecognized Figure! p
    Unrecognized Figure! p
    Unrecognized Figure! s
    Unrecognized Figure! t
    Unrecognized Figure! w
    Unrecognized Figure! w

    Also, when I deliberately use an unrecognized file such as ! in:

    postc 3 4 !

    the output is:

    Unrecognized Figure! !

    which is normal behavior. I have no idea what the deal is.

    Also one more very strange thing, the output of:

    postc 3 4 ^

    is:

    More?

    I thought my program was talking to me!! Anyways, I don't really know enough about command line code so I am a bit absent of ideas.
    Thank you for the help so far guys!

  12. #12
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    The output from
    Code:
    postc 3 4 *
    is no mystery. The '*' character is expanded to the names of all files in the current directory, and your program is reading (and now writing) the first character of each name. So we see that you have 12 files in that directory and their names begin with the letters b b e e p p p p s t w w.

    Your program isn't talking to you. The Windows shell is talking to you. I think I have found the answer to the "More?" result, and it is probably the answer to your underlying problem as well. It says here that the Windows XP shell (and presumably also the Vista shell) uses the carat ('^') as an escape character, so when you wrote
    Code:
    postc 3 4 ^
    it was not a complete command and the shell is prompting you to complete it. Therefore if you write
    Code:
    postc 3 4 ^*
    I believe you will get the result you want. The mystery, though, is why
    Code:
    postc 3 4 "*"
    doesn't work, since that Microsoft document says that
    ... the ampersand ... must be preceded by the escape character (^) or quotation marks ...
    . Please post the output you get when you use
    Code:
    postc 3 4 "*"
    I'd like to know why that didn't work.

  13. #13
    Registered User
    Join Date
    May 2009
    Posts
    12
    R.Stiltskin :

    I have tried both the ^ and quatation marks to escape the *, however neither worked.

    Here are there outputs,

    Input:

    postc 3 4 +

    Output:

    = 7


    Input:

    postc 3 4 ^*

    Output:

    Unrecognized Figure! b
    Unrecognized Figure! b
    Unrecognized Figure! e
    Unrecognized Figure! e
    Unrecognized Figure! p
    Unrecognized Figure! p
    Unrecognized Figure! p
    Unrecognized Figure! p
    Unrecognized Figure! s
    Unrecognized Figure! s
    Unrecognized Figure! s
    Unrecognized Figure! t
    Unrecognized Figure! w
    Unrecognized Figure! w



    Input:

    postc 3 4 "*"

    Output:

    Unrecognized Figure! b
    Unrecognized Figure! b
    Unrecognized Figure! e
    Unrecognized Figure! e
    Unrecognized Figure! p
    Unrecognized Figure! p
    Unrecognized Figure! p
    Unrecognized Figure! p
    Unrecognized Figure! s
    Unrecognized Figure! s
    Unrecognized Figure! s
    Unrecognized Figure! t
    Unrecognized Figure! w
    Unrecognized Figure! w


    Sorry man, it's giving the same error.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    In Windows, *INSIDE* a string, isn't a backslash the escape char?

    "\*"

  15. #15
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Are you still running exactly the same code as you posted in post #1? Especially the line that says:
    Code:
             case '*':      /*   <-- trouble maker  any other characters work, such as # and x  */

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Character literals incorrectly interpreted
    By DL1 in forum C Programming
    Replies: 11
    Last Post: 04-05-2009, 05:35 PM
  2. wide character (unicode) and multi-byte character
    By George2 in forum Windows Programming
    Replies: 6
    Last Post: 05-05-2007, 12:46 AM
  3. <string> to LPCSTR? Also, character encoding: UNICODE vs ?
    By Kurisu33 in forum C++ Programming
    Replies: 7
    Last Post: 10-09-2006, 12:48 AM
  4. syntax error when defining vectors
    By starkhorn in forum C++ Programming
    Replies: 5
    Last Post: 09-22-2004, 12:46 PM
  5. Character handling help
    By vandalay in forum C Programming
    Replies: 18
    Last Post: 03-29-2004, 05:32 PM