Thread: I don't understand this.

  1. #1
    Registered User
    Join Date
    Apr 2010
    Location
    Portland, OR
    Posts
    11

    I don't understand this.

    Here is the assignment that I need to do. How should I be approaching this? I'm a 3.8 GPA student and I fear I won't pass this C programming. S.O.S.

    The goal of this assignment is to work with repetition and selection structures, with a focus on repetition. As in past assignments you will create a small calculator application, although it will not be an extension of the earlier calculators. Instead, your program should present the user with a list of options, read the user's input, process the option, and then repeat until the user requests to end the program. The options you must accept and process are:
    Code:
        * 'Q' or 'q': Quit the program
        * 'Eval(<exp>)': Evaluate a simple expression
        * '!n': Evaluate an integer factorial
        * 'P(n,k)': Count the number of permutations of length k in a string of length n.
    The details of each option are presented below. In this assignment you may use the do{} while(), while() {}, or for(;{} structures, but you may not use the goto or other unconditional repetition structures. Also, you may not use the math.h library or any other external math library to calculate your results - the goal of this assignment is to build your own code! Further, in this assignment you must accept input and display output as shown in the example below - you do not have the option of altering the input sequence or output sequence in this assignment.

    The output below shows the input and output style that you should have in your program.
    Code:
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: P(3,2)
    A string of 3 characters has 6 permutations of length 2
    
    
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: Eval(2 ^ 3)
    2 ^ 3 = 8
    
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: Eval(2 - 1023)
    2 - 1023 = -1021
    
    
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: Eval(3.4 % 5)
    3.40 % 5.00 = 3.00
    
    
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: !5
    5! = 120
    
    
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: !13
    13! = 6227020800
    
    
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: P(3,2)
    A string of 3 characters has 6 permutations of length 2
    
    
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: P(4,2)
    A string of 4 characters has 24 permutations of length 2
    
    
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: q
    Sorry it's so long, but I feel like you should see all of it.

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Okay, so what have you tried so far?
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  3. #3
    Registered User
    Join Date
    Apr 2010
    Location
    Portland, OR
    Posts
    11
    How should I approach this? what kind of structure? I havent done anything yet, but I've been writing programs not thinking about it firstly, and Im not doing well. so enlighten me please? pretty please?

  4. #4
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Well your first concern should be to get a basic menu structure going on, and leave the control for what you actually do in that case empty for now. That requires you to parse what the user inputs, see if the string he has inputted is a valid choice or not. If it is a valid choice, which one is it?

    1) Did he type "Q" or "Quiet"? Only the first is valid
    2) Did he type Eval(<expr>)? Is the expression valid (i.e. does it contain two operands and a valid operation symbol in between the operands? Are these operands numbers and not something else?
    3) Did he type !6 or !shhhhh? Is he asking for a factorial or just messing with me.
    4) Did he type P(2,3) or P(trickor,treat)?
    5) Did he type something that doesn't even resemble any of the commands?

    See what I am getting at?
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  5. #5
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    You can have an integer say:

    int choice;

    to represent which one of the four it is, or to be negative in case the input is invalid.

    Then just switch(choice) and for each valid case perform whatever calculations are needed. You can then use functions outside of main to do the actual calculations so that you keep your switch structure clean and easy to understand.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Feeling somewhat generous, here's a start I just whipped up:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    enum Choice { Invalid = -1, Quit, Eval, Fact, Perm };
    
    void printMenu();
    void printMenuOption (const char * const opt, const char * const desc);
    enum Choice getMenuChoice();
    
    int main()
    {
        char buf[256] = { 0 };
        printMenu();
        enum Choice c = getMenuChoice(buf, sizeof(buf));
        while (c != Quit)
        {
            // perform task
            if (c != Invalid)                                                         
                printf("Got task %s\n", buf);
    
            printMenu();
            c = getMenuChoice(buf, sizeof(buf));
        }
        printf("Bye!\n");
        return 0;
    }
    
    void printMenuOption (const char * const opt, const char * const desc)
    {
        printf("%11s - %s\n", opt, desc);
    }
    
    void printMenu()
    {
        printf("Enter one of the following options:\n");
        printMenuOption("Q", "Quit the program");
        printMenuOption("Eval(<exp>)", "Evaluate a simple expression");
        printMenuOption("!", "Evaluate an integer factorial");
        printMenuOption("P(n,k)", "Count the k-permutations of a string of n charac\
    ters");
        printf("\nEnter your option: ");
    }
    
    enum Choice getMenuChoice(char *buf, const size_t len)
    {
        enum Choice choice = Invalid;
        if (fgets(buf, len, stdin) == NULL)
            return choice;
        buf[strlen(buf) - 1] = 0;
        switch (buf[0])
        {
        case 'Q':
        case 'q':
            choice = Quit;
            break;
        case 'E':
            // Let's be optimistic                                                  
            choice = Eval;
            break;
        case '!':
            choice = Fact;
            break;
        case 'P':
            choice = Perm;
            break;
        default:
            break;
        }
    
        return choice;
    }
    Not perfect, but might get you started.

  7. #7
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by rags_to_riches View Post
    Feeling somewhat generous, here's a start I just whipped up:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    enum Choice { Invalid = -1, Quit, Eval, Fact, Perm };
    
    void printMenu();
    void printMenuOption (const char * const opt, const char * const desc);
    enum Choice getMenuChoice();
    
    int main()
    {
        char buf[256] = { 0 };
        printMenu();
        enum Choice c = getMenuChoice(buf, sizeof(buf));
        while (c != Quit)
        {
            // perform task
            if (c != Invalid)                                                         
                printf("Got task %s\n", buf);
    
            printMenu();
            c = getMenuChoice(buf, sizeof(buf));
        }
        printf("Bye!\n");
        return 0;
    }
    
    void printMenuOption (const char * const opt, const char * const desc)
    {
        printf("%11s - %s\n", opt, desc);
    }
    
    void printMenu()
    {
        printf("Enter one of the following options:\n");
        printMenuOption("Q", "Quit the program");
        printMenuOption("Eval(<exp>)", "Evaluate a simple expression");
        printMenuOption("!", "Evaluate an integer factorial");
        printMenuOption("P(n,k)", "Count the k-permutations of a string of n charac\
    ters");
        printf("\nEnter your option: ");
    }
    
    enum Choice getMenuChoice(char *buf, const size_t len)
    {
        enum Choice choice = Invalid;
        if (fgets(buf, len, stdin) == NULL)
            return choice;
        buf[strlen(buf) - 1] = 0;
        switch (buf[0])
        {
        case 'Q':
        case 'q':
            choice = Quit;
            break;
        case 'E':
            // Let's be optimistic                                                  
            choice = Eval;
            break;
        case '!':
            choice = Fact;
            break;
        case 'P':
            choice = Perm;
            break;
        default:
            break;
        }
    
        return choice;
    }
    Not perfect, but might get you started.
    Uhm NO. This doesn't even compile.

    Also, int main() is to be avoided in C. See FAQ.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  8. #8
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    It probably doesn't compile under Visual Studio, but using an up-to-date compiler and standards it works just fine.
    Code:
    r2r$ gcc -Wall -pedantic -std=c99 -o what what.c
    r2r$ ./what
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: !3
    Got task !3
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: P(3,6)
    Got task P(3,6)
    Enter one of the following options:
              Q - Quit the program
    Eval(<exp>) - Evaluate a simple expression
              ! - Evaluate an integer factorial
         P(n,k) - Count the k-permutations of a string of n characters
    
    Enter your option: q
    Bye!
    r2r$
    It can be made to compile under C89 with the following change:
    Code:
    char buf[256] = { 0 };
    enum Choice c = Invalid;
    printMenu();
    while ((c = getMenuChoice(buf)) != Quit)
    {
        // perform task                                                         
        if (c != Invalid)                                                      \
             printf("Got task %s\n", buf);
    
        printMenu();
    }
    Also, int main() is to be avoided in C. See FAQ.
    Oh, sorry it should be
    Code:
    int main(void)
    .
    Last edited by rags_to_riches; 05-09-2010 at 10:15 AM. Reason: Fixed

  9. #9
    Registered User
    Join Date
    Apr 2010
    Location
    Portland, OR
    Posts
    11
    I see what you're getting at. The order in which these processes is to be can somewhat confuse me. This is more than enough to get me started. thanks to all, especially dude that wrote code. I won't be copying it, just referencing.

  10. #10
    Registered User
    Join Date
    Apr 2010
    Location
    Portland, OR
    Posts
    11
    Quote Originally Posted by claudiu View Post
    You can have an integer say:

    int choice;

    to represent which one of the four it is, or to be negative in case the input is invalid.

    Then just switch(choice) and for each valid case perform whatever calculations are needed. You can then use functions outside of main to do the actual calculations so that you keep your switch structure clean and easy to understand.
    I am starting to understand what you mean by this. My instructor is awful, but you put it into better words than he did. f.m.l.

    When I get confused next I will post up what I have. thanks man.

  11. #11
    Registered User
    Join Date
    Apr 2010
    Location
    Portland, OR
    Posts
    11
    So after 5 hours at the tutoring center with another guy in my class. We finished most of this lab. any thoughts?

    One thing, the factorial won't work past double digits. I get negative numbers. I think this is because it's reading one character?

    one thing to remember, I am using dev c++ (i know, i know) and compiling through that program it runs exactly like it should.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define  bufSize 8192
    int main() {
         int         varA, varB, i;
         int         operA=1;
         char        userInput[bufSize], char1;
         char        doneFlag = 'f';
         
         do {
                  printf("Enter one of the following options: \n\
                  Q - Quit the following program\n\
    Eval(int * int) - Evaluate a simple expression\n\
                  ! - Evaluate an integer factorial\n\
             P(n,k) - Count the k-permutations of a string of n characters\n\
         \n\
         Enter your option:");
         fgets(userInput,bufSize,stdin);
         
         
         if (userInput[0] == 'q' || userInput[0] == 'Q') {
             doneFlag = 't';
             
             } else if (strstr(userInput,"Eval\n") != NULL) {
                    printf("Enter your option: ");
                    scanf("%*c%*c%*c%*c%*c%d%*c%c%*c%d%*c%*c",&varA,&char1,&varB);
                    
             if(char1 == '+')
               {operA = varA + varB;}
               else if(char1 == '-')
               {operA = varA - varB;}
               else if(char1 == '*')
               {operA = varA * varB;}
               else if(char1 == '/')
               {operA = varA / varB;}
               else if(char1 == '%')
               {operA = varA % varB;}
               else if(char1 == '^')
               {for(i = 1; i <= varB; i++)
               operA *= varA;
               }
               printf("%d %c %d = %d\n\n",varA,char1,varB,operA);
                    
             } else if (userInput[0] == '!') {
                    printf("Enter your option: ");
                    scanf("%d%*c",&varA);
                    for(i = 1; i <= varA; i++)
                    operA *= i;
                    printf("%d! = %d",varA,operA);
                    
                       
             } else if (userInput[0] ==  'p' || userInput[0] == 'P') {
                    printf("You entered \n");
                    } else {
                           printf("\n? no valid option");
                           }
                           
         operA = 1;                  
         scanf("%*c"); 
         } while (doneFlag == 'f');
         return 0;
    }

  12. #12
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Well it's not really correct at least in my interpretation of the requirements. What happens if the user enters "quiet' as a command? your program quits when in fact it's supposed to print something like "invalid command"
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  13. #13
    Registered User
    Join Date
    Apr 2010
    Location
    Portland, OR
    Posts
    11
    Quote Originally Posted by claudiu View Post
    Well it's not really correct at least in my interpretation of the requirements. What happens if the user enters "quiet' as a command? your program quits when in fact it's supposed to print something like "invalid command"
    I also forgot to mention that we hadn't finished the permutations part yet.

    It's reading the Q in quiet? Other strings of characters show "no valid option" if you delete the unnecessary ? that's in the code. lol.

  14. #14
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Look I haven't actually run your code I admit, but make sure you run it with all the possible and impossible inputs. It should be able to handle the monkey test(i.e. a monkey typing on the keyboard something like oashdandbkjadfsfhfhohoafsihhjoadodojadfsio;la[pqewpoqw+)

    Get it?
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  15. #15
    Registered User
    Join Date
    Apr 2010
    Location
    Portland, OR
    Posts
    11
    Quote Originally Posted by claudiu View Post
    Look I haven't actually run your code I admit, but make sure you run it with all the possible and impossible inputs. It should be able to handle the monkey test(i.e. a monkey typing on the keyboard something like oashdandbkjadfsfhfhohoafsihhjoadodojadfsio;la[pqewpoqw+)

    Get it?
    what I am saying is you are correct it quits the program from reading q in quiet, other strings of random "monkey" characters, even those including q not as the first character show "no valid option". how can i stop it from reading q as quit if other characters are involved?

    also, any idea about the factorial issue? some double digits give me negative numbers..

Popular pages Recent additions subscribe to a feed