Here is my assignment rules, i am stuck and cannot find what it is i am doing wrong. If some one could help me i would appreciate it

* The main routine must be a 'manager' routine, which means
o The function can declare variables
o The function can call other functions
o The function can save return values from functions and pass those values to other functions
o The function must not perform any task other than the management of other functions
o The function may not call any function other than user-defined functions

* All formal parameters are read-only, even if passed by reference. Functions may not modify their formal parameters

* All variables must be block scope variables defined within the function where they are references. No file scope or external variables

* All user-defined functions must have a function declaration (prototype) before the definition of the main function, and all user-defined functions must be defined after the main routine

* All user-defined functions must be highly cohesive and loosely coupled. In other words, you may perform only one task per function.


Here is what i have:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define bufSize 2048



int calculateEval (char *);
int calculateN (char *);
int calculatePNK (char *);


char input (char *);
int main  (){
int intVal[10];
char eval,calcN,calcPNK;
char * userInput;

userInput = input();
eval = calculateEval(userInput);
calcN = calculateN(userInput);
calcPNK = calculatePNK(userInput);


scanf("%*c");
    return 0;
}
char input (char *){
  char userInput [bufSize];
  
     printf("Enter one of the following options: \n\
             Q - Quit the program\n\
             Eval(<exp>) - Evaluate a simple expression\n\
             ! - Evaluate an integer factorial\n\
             P(n,k) - Count k-permutations of a string of n characters\n\
             Enter your option: ");
     fgets(userInput,bufSize,stdin);
     
     return userInput[bufSize];
}
int calulateEval (char *){
     char userInput [bufSize];
     int varA, varB, exprA;
     char evalOp;
     
     sscanf (userInput,"Eval(%d%c%d)", &varA, &evalOp, &varB);
          switch(evalOp) {
                   case '+':
                   exprA = varA + varB;
                   printf("%d%c%d=%d\n", varA, evalOp, varB, exprA);
                   break;
                   case '-':
                   exprA = varA - varB;
                   printf("%d%c%d=%d\n", varA, evalOp, varB, exprA);
                   break;
                   case '/':
                   exprA = varA / varB;
                   printf("%d%c%d=%d\n", varA, evalOp, varB, exprA);
                   break;
                   case '*':
                   exprA = varA * varB;
                   printf("%d%c%d=%d\n", varA, evalOp, varB, exprA);
                   break;
                   case '%':
                   exprA = varA % varB;
                   printf("%d%c%d=%d\n", varA, evalOp, varB, exprA);
                   break;
                   case '^':
                   exprA = pow(varA,  varB);
                   printf("%d%c%d=%d\n", varA, evalOp, varB, exprA);
                   break;
                   default;
                           exprA = 0;
                           printf("?'%c' is not a valid operator", evalOp);
               }
               return 0;
          }
int calculateN (char *){
     char userInput [bufSize];
     int factorial, idx1, varA;
     
     sscanf(userInput,"!%d",&varA);  
          factorial = 1.0;
          idx1 = 1;
             for(idx1 = 1; idx1 <= varA; idx1++) {
             factorial = factorial * (float)idx1;
             }
          printf("%d! = %.0f\n",varA, factorial);    

          return 0;
          }
int calculatePNK (char *){
     char userInput [bufSize];
     int varA, permutA, varB,factorial, idx1, idx2, factorial2, varN, varK, numPerms,
     varNK;
     
     sscanf(userInput,"P(%d %c %d)",&varA, &permutA, &varB);
          printf("A string of %d characters has ",exprA);
          factorial = 1.0;
          idx1 = 1;
             for(idx1 = 1; idx1 <= varN; idx1++) {
             factorial = factorial * (float)idx1;
             }   
          varNK = varN - varK;
          factoral2 = 1.0;  
          idx2 = 1;
             for(idx2 = 1; idx2 <= varNK; idx2++) {
             factoral2 = factoral2 * (float)idx2;
             }
          numPerms = factorial / factoral2;  
          printf("%d permutations of length %d\n",numPerms,varK);
     return 0;
     }

While posting the assignment in this case it could be helpful, it would be more helpful to from you what the program is supposed to do, what is doing that it is not supposed to do. That give us an idea of your comprehension of the task. Posting some errors if any could speed the process as well.

"Anywho"! As stands I would have to guess what you mean by: "what it is i am doing wrong"

o The function may not call any function other than user-defined functions

If that part is referring to any function, you are screwed since any call to scanf(), printf() etc are functions not defined by you.
If it is referring only by the main function, then you are screwed since scanf("%*c"); is not defined by you.

Let's look at first function.

char input (char *){
  char userInput [bufSize];
  
     printf("Enter one of the following options: \n\
             Q - Quit the program\n\
             Eval(<exp>) - Evaluate a simple expression\n\
             ! - Evaluate an integer factorial\n\
             P(n,k) - Count k-permutations of a string of n characters\n\
             Enter your option: ");
     fgets(userInput,bufSize,stdin);
     
     return userInput[bufSize];
}

If input doesn't require parameter then you must define it as char input(void) As it stands...

char input (char *);
char input (char *) { /* definition here */ }
userInput = input();

...are at odds of each other.
I suggest you take a look at the rest of those functions, there suffer of same illness.
An example.

#include <stdio.h>

int sum (int, int); /* in prototype, specific names are not necessary */

int main (void)
{
    sum(2, 2); /* calling function sum */
    return 0;
}

int sum (int one, int two) /* specific name is necessary if any */
{
    return one + two; /* now you can use the names */
}

char userInput [bufSize]; is an array of characters. char input() says you are returning a character alone. You return character userInput[2048] whatever that is.

You can not return an array of characters, but you can return a pointer to it.

char *input(void)
{
    char arrayofchars[20];
    /* blah, blah */
    return arrayofchars;
}

The problem is that arrayofchars[20] is a local variable, and it will be destroyed as soon as the function is finished, leaving you with a pointer to something that might or might not have the data you hope.

To remedy the problem you can pass it a chunk of memory already available via an argument, use some memory available in the scope of the function, or define some in the heap via dynamic allocation.

char *input(void)
{
    /* arrayofchars has been defined somewhere in the code, but not in the function */
    fgets(arrayofchars, sizeof arrayofchars, stdin);
    return arrayofchars; 
}

or

char *input(char *arrayofchars, int buffersize)
{
    fgets(arrayofchars, buffersize, stdin);
    return arrayofchars;
}

or

#include <stdlib.h>

char *input(void)
{
    int size = 50;
    char *arrayofchars = malloc(size);
    fgets(arrayofchars, size, stdin);
    return arrayofchars;
}

Of course, in all of them proper checks must be done, and in the last one the dynamic memory must be free() after done with it.

And now that all that has been said and done. If what you want is only a single char, an array of 2048 char userInput [bufSize] is not necessary. Just an int is sufficient, and fgets() is not needed as well since getchar() will do, unless you want to use fgets() to handle input management errors.

See what happens when you dump your assignment and do not specify the issue? You get more than you bargain for, or nothing at all.

Edited 6 Years Ago by Aia: n/a

I got a wealth of information, could you teach my c class? I don't understand my prof at all most of the time. My problem lies in the fact that i am unsure of how to tie it all in from within the main function. I know i am going to have to have a selection function that it differs to, but getting it all called without using a switch in the main has stumped me. I wish i understood this stuff, and would probably get a better handle on it if i could apply it to something I know. Thanks for your help, i really appreciate it.

I would suggest to take the task little by little. Compiling often and testing before moving on to another function that does something. That's the beauty of breaking it into functions.
There's nothing wrong with just starting with a single function first. Like char input (char *){} ; by the way, let's correct it: char input(void) {} if you still want to return a char (be mindful that many functions that read a single char, still returns an int to accommodate EOF as an error ).

char key_answer = input();

Once you get that one down, you can rest assure that unless you modify it, the returned value is correct. It compiles without errors or warnings. Now you can use its value and create another function that takes that value without modifying it.
e.g. (as illustration)

double double_or_nothing (const char response); /* const is there so the compiler will bark at you if something tries to modify it */

where the call can be like

double result = double_or_nothing (key_answer);

Compile and test often, so bugs and flaws in the flow doesn't overwhelm you to the point of extending your arms into the air, and wishing you would never had taken this path.

As an added bonus, if something goes wrong and you get stuck, you will not be lost. You'll never have to say again: "cannot find what it is i am doing wrong". You'll be able to give details of what is doing incorrectly, and exactly where it fails.

Edited 6 Years Ago by Aia: n/a

So I followed your advice and put everything together, but as seperate programs, and i cant get the main function to pass the info from my menu function to my equation problem. could you show me how to pass the info and explain it. I have read a ton of stuff and i just dont get it. I hate this class and i am glad that i only have to take one. Just sucks this is 1 out of 3 assignments due next Sunday. Well here is the code for the assignment. At least i think that is the problem. and just for the sake of argument, pretend like i am an idiot when it comes to programming, well because i am ;)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int intFunction (void);
float floatFunction (void);
float intFloatFunction (void);
int menu(int);



int main(){
     int userInput;
     
    menu (userInput);
          
     switch(userInput){
          case '1':  int intFunction (void);
          break;
          case '2': float floatFunction (void);
          break;
          case '3': float intFloatFunction (void);
          default: ("You have entered an invalid option.\n");
}
     
     return 0;
}
int menu (int){
     int userInput;
     
     printf(" Please select form the following:\n\
          1: An int function.\n\
          2: A float function.\n\
          3: A mixed function.\n\n");
          scanf("%d%*c");
     return userInput;
}
int intFunction (int var1,char op1,int var2,char op2,int var3,char op3,int var4,
char op4,int var5,char op5, int var6)
{
                    
     int sum1, sum2, sum3, sum4,sum5;               
                    
     printf("Enter an operation with the following format:\n\
    (int?int)?(int?int)?(int?int):\n");
    
    scanf("(%d%c%d)%c(%d%c%d)%c(%d%c%d)%*c", 
    &var1,&op1,&var2,&op2,&var3,&op3,&var4,&op4,&var5,&op5,&var6); 
    
    
         
     switch(op1){
                case '+':sum1 = var1 + var2;
                             break;
                    case '-':sum1 = var1 - var2;
                             break;                            
                    case '*':sum1 = var1 * var2;
                             break;
                    case '/':sum1 = var1 / var2;
                             break;
                    case '%':sum1 = var1 % var2;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.1?");}   
     switch(op2){   
                    case '+':sum2 = var3 + var4;
                             break;                             
                    case '-':sum2 = var3 - var4;
                             break;
                    case '*':sum2 = var3 * var4;
                             break;                             
                    case '/':sum2 = var3 / var4;
                             break;
                    case '%':sum2 = var3 % var4;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.2?");}  
    
     switch(op3){   
                    case '+':sum3 = var5 + var6;
                             break;                             
                    case '-':sum3 = var5 - var3;
                             break;
                    case '*':sum3 = var5 * var3;
                             break;                             
                    case '/':sum3 = var5 / var6;
                             break;
                    case '%':sum3 = var5 % var6;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.3?");} 
    
     switch(op4){   
                    case '+':sum4 = sum1 + sum2;
                             break;                             
                    case '-':sum4 = sum1 - sum2;
                             break;
                    case '*':sum4 = sum1 * sum2;
                             break;                             
                    case '/':sum4 = sum1 / sum2;
                             break;
                    case '%':sum4 = sum1 % sum2;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.2?");} 
      
      
      switch(op5){   
                    case '+':sum5 = sum3 + sum4;
                             break;                             
                    case '-':sum5 = sum3 - sum4;
                             break;
                    case '*':sum5 = sum3 * sum4;
                             break;                             
                    case '/':sum5 = sum3 / sum4;
                             break;
                    case '%':sum5 = sum3 % sum4;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.2?");} 
     
     printf("((%d%c%d)%c(%d%c%d)%c(%d%c%d)= %d", var1, op1, var2, op2, var3,
      op3, var4, op4, var5, op5, var6, sum5);
       return 0;
        
}
      
float  func2 (float var1, char op1,float var2,char op2,float var3,
   char op3,float var4){
   printf("Enter an operation with the following format:\n\
          (float?float)?(float?float):\n");
    
    scanf("(%f%c%f)%c(%f%c%f)%*c", 
          &var1,&op1,&var2,&op2,&var3,&op3,&var4); 
     
     
         float sum1, sum2, sum3;
     switch(op1){
                case '+':sum1 = var1 + var2;
                             break;
                    case '-':sum1 = var1 - var2;
                             break;                            
                    case '*':sum1 = var1 * var2;
                             break;
                    case '/':sum1 = var1 / var2;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.1?");}   
     switch(op2){   
                    case '+':sum2 = var3 + var4;
                             break;                             
                    case '-':sum2 = var3 - var4;
                             break;
                    case '*':sum2 = var3 * var4;
                             break;                             
                    case '/':sum2 = var3 / var4;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.2?");}  
    
     switch(op3){   
                    case '+':sum3 = sum1 + sum2;
                             break;                             
                    case '-':sum3 = sum1 - sum2;
                             break;
                    case '*':sum3 = sum1 * sum2;
                             break;                             
                    case '/':sum3 = sum1 / sum2;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.3?");} 
                             
     printf("(%f.3c%f.3)%c(%f.3%c%f.3)=%f.3", var1, op1, var2, op2, var3,
      op3, var4, sum3);
      
   return 0;
}

float intFloatFunction (int var1, char op1,int var2,char op2,float var3,
   char op3,float var4)
{
     int sum1;
     float sum2, sum3;
        
        
          printf("Enter an operation with the following format:\n\
               (int?int)?(float?float):\n");
    
          scanf("(%d%c%d)%c(%f%c%f)%*c", 
               &var1,&op1,&var2,&op2,&var3,&op3,&var4); 
               
        
     switch(op1){
                case '+':sum1 = var1 + var2;
                             break;
                    case '-':sum1 = var1 - var2;
                             break;                            
                    case '*':sum1 = var1 * var2;
                             break;
                    case '/':sum1 = var1 / var2;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.1?");}   
     switch(op2){   
                    case '+':sum2 = var3 + var4;
                             break;                             
                    case '-':sum2 = var3 - var4;
                             break;
                    case '*':sum2 = var3 * var4;
                             break;                             
                    case '/':sum2 = var3 / var4;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.2?");}  
    
     switch(op3){   
                    case '+':sum3 = (float)sum1 + sum2;
                             break;                             
                    case '-':sum3 = (float)sum1 - sum2;
                             break;
                    case '*':sum3 = (float)sum1 * sum2;
                             break;                             
                    case '/':sum3 = (float)sum1 / sum2;
                             break;
                             default:
                             printf("ERROR @ STAGE 1.3?");} 
                        
     printf("(%dc%d)%c(%f%c%f)=%f", var1, op1, var2, op2, var3,
      op3, var4, sum3);
           
                             
return 0;
}

I'll use your example to give you something to think about it.
You have a prototype named: int menu(int); with a parameter of type int.

int menu (int /* missing an identifier */){
     int userInput;
     
     printf(" Please select form the following:\n\
          1: An int function.\n\
          2: A float function.\n\
          3: A mixed function.\n\n");
          scanf("%d%*c", /* missing pointer &userInput */);
     return userInput;
}

However, let's say you don't need that parameter. The prototype would be int menu(void); and the function will be defined as:

int menu ()
{
     int userInput;
     
     printf(" Please select form the following:\n\
          1: An int function.\n\
          2: A float function.\n\
          3: A mixed function.\n\n");
          scanf("%d%*c", &userInput); /* not a good solution but that would be another topic */
     return userInput;
}

According to your posted specifications, main() can have variables and can accept returns of called functions.

int main (void)
{
    int answer_n;
    
    
    /*
     * menu returns an int, let's have an int, then, to hold it
     */
     answer_n = menu(); /* that's how you call the function */

     
    /* answer_n, supposedly, holds the choice now, use it as argument in another function */

    /* this is only an example */
    parse_answer(anwer_n);

    return 0;

}
int intFunction (void);
float floatFunction (void);
float intFloatFunction (void);

Those functions cannot have void as parameters, you have defined them to accept arguments.

switch(userInput){
          case '1':  int intFunction (void);
          break;
          case '2': float floatFunction (void);
          break;
          case '3': float intFloatFunction (void);
          default: ("You have entered an invalid option.\n");

Improper syntax calling functions. Remove ('') around the 1, 2, and 3.

case 1: /* no '' since there are not chars */
             result = intFunction ( argument1, argument2 ); /* return something, accept something */
             break;
int intFunction (int var1,char op1,int var2,char op2,int var3,char op3,int var4,
char op4,int var5,char op5, int var6)

A good indication that a function is doing perhaps too much would be the amount of parameters that accepts. More than four, could be a rule of thumb to think if it can be re-designed to do less. ( Unless, you are coding for Microsoft, they pay by the amount of arguments a function accepts; more the better ;) )
You do not have that option anyway. The requirements says:

* All user-defined functions must be highly cohesive and loosely coupled. In other words, you may perform only one task per function.

Also pay attention to:

* The main routine must be a 'manager' routine, which means
...
o The function must not perform any task other than the management of other functions

Not only it tells you what main() can do but what it can not do. A switch might or might not be acceptable, unless is considered part of "management of other functions"

Edited 6 Years Ago by Aia: n/a

Yes it is a management function, accepting the return form the menu and managing the decision of which function to call afterwards.

int main(void){
     int userInput;
     
    userInput = menu();
          
     switch(userInput){
          case 1:  int intFunction (int, int *);
          break;
          case 2: float floatFunction (int, int *);
          break;
          case 3: float intFloatFunction (int, int *  );
          default: ("You have entered an invalid option.\n");
}/* the switch manages which function to call based on the information from the menu function*/

inside the functions, i do not really need it to return anything, it handles everything inside, i just need it to do what it is supposed to do and return back to the main. I forgot to add a quit function but that shouldnt be to big of a problem.

if i were to go from:

int intFunction (int var1,char op1,int var2,char op2,int var3,char op3,int var4,
char op4,int var5,char op5, int var6)
{
                    
     int sum1, sum2, sum3, sum4,sum5;

to this because i dont need it to actually return anything back to the main function, it is just done here.

int intFunction (void)
{
                    
     int sum1, sum2, sum3, sum4,sum5,  var1,var2,var3,var4,var5,var6;               
     char  op1,op2,op3,op4,op5;

but i still cant get the main to call the other functions based on the return from menu. I dont understand how to use parse or what it does, and i am unsure of how to use the

1.
      case 1: /* no '' since there are not chars */
   2.
      result = intFunction ( argument1, argument2 ); /* return something, accept something */
   3.
      break;

scratch that i figured the second thing out it looks like this:

switch(userInput){
          case 1:  userInput = int intFunction (void);
          break;
          case 2:  userInput = float floatFunction (void);
          break;
          case 3:  userInput = float intFloatFunction (void);
          default: ("You have entered an invalid option.\n");

but i am getting an error for all three and i am unsure how to fix it

17 C:\Users\a\Desktop\Untitled1.cpp expected primary-expression before "int"
i am getting this for all three points in the switch

17 C:\Users\a\Desktop\Untitled1.cpp expected primary-expression before "int"
i am getting this for all three points in the switch

C code source has the extension *.c, you are compiling C++ (*.cpp) which is not the same. Save your work as *.c, then compile.

scratch that i figured the second thing out it looks like this:

switch(userInput){
          case 1: userInput = int intFunction (void);
          break;
          case 2:  userInput = float floatFunction (void);
          break;
          case 3:  userInput = float intFloatFunction (void);
          break;
          default: ("You have entered an invalid option.\n");

but i am getting an error for all three and i am unsure how to fix it

Go back to my previous posts and re-read them. I have mention several times how to call a function within another function. The part in red are incorrect, think about it and find why. The part in green is worth to take a look and think about it.

Edited 6 Years Ago by Aia: n/a

This article has been dead for over six months. Start a new discussion instead.