Skip to main content
Rollback to Revision 3
Source Link
pacmaninbw
  • 24.9k
  • 11
  • 46
  • 109

EDIT: removed alternative implementation that wasn't much better.

Does anyone have any suggestions or helpful advice for reducing the redundancy with add/sub (if its even possible)? Its not entirely necessary, but I'd appreciate any assistance.

EDIT: Updated semi-improved code, now with more functionality: Example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define min(a, b) ((a) < (b) ? (a) :void calc(b))
#define maxItems 15

typedef struct _Menu {
  int count;
  char *items[maxItems];
} Menu;

char *choices[] = {"Exit", "Addition", "Subtraction", "Multiplication"argc, "Division",char "Modulo"**argv, "Reverse Input"};
int count = sizeof(choices)/sizeof(choices[0]);

int printMenu(const Menu *menuop){
  int ch;
  printf("\n");
  for (int i=0; i<menu->count; i++) 
    printf("%d. %s\n", i, menu->items[i]);

  printf("\nMenu Item: ");
 = scanf("%d"1,&ch);
  return ch;
}

void strrev(char *str){

    if (str == 0)
      return;

    if (*strs === 0)
      return;

    /* get range */
    char, *startx = str;0;
    char *endsign = start + strlen(str) - 1;op /*== -1 for \0 */
    char temp;

    /* reverse */
    while (end > start){
      /* swap */
      temp = *start;
      *start = *end;
      *end = temp;

      /* move */
      ++start;
  ? '+' :  -'-end;
    }
}';

void rev(int argc, char **argv){
  for if(int i = argc-1; i > 0; --i){
    strrevisHex(argv[i]);
    printf("%s ", argv[i]);
  }
  
  printf("\n");
}

int addstrlen(int a, int bargv[i]){
  return a+b;
}

int sub(int a, int b){
  return a-b;
}

int mult(int a, int b){
  return a*b;
}

float divi(int a, int b){
  returns a/b;
}

int= mod(int a, int b){
  return a%b;
}

intx applyOperator=convertHex(int argc, char **argvargv[i], int (*op)strlen(int, intargv[i])) {
  int retval = strtol(argv[0], NULL, 0);

  for (int i = 1; i < argc; ++i) {else
    retvals = op(retval, strtolatoi(argv[i], NULL, 0));
  }

  return retval;
}

void printList(int argc, char **argv, const char *sep) {
  printf("%s", argv[1]);
  
  for (int i = 2; i < argc; ++i2;i<argc;i++) {
   
    printf("%s%s", sep, argv[i]);
  }
}

//Attempting implementation of function dispatch tableAdd
int (*calc[])(int, int) = {add, sub, mult};

int mainif(intop argc,char**== argv1){
 
  Menu menu;
  menu.count = min(count, maxItems);
  
  for (int i=0; i < menu.count; i++)
    menu.items[i] = choices[i];

  if(argc < 3)
    fprintfisHex(stderrargv[i], "You must enter at least two arguments.\n");

  else ifstrlen(argc > 16argv[i])
    fprintf(stderr, "You cannot enter more than 15 arguments.\n");

  else{

    int ch=1;
    while(ch!=0){   
      ch = printMenu(&menu);

      switch(ch){
        case 0:
          exit(0);
          break;

        case 1:
          printList(argc, argv, " + ");
        s += printf("x = %d\n", applyOperatorconvertHex(argc, argvargv[i], calc[0]strlen(argv[i]));
          break;
        
        case 2:
          printList(argc, argv, " - ");
          printf(" = %d\n", applyOperator(argc, argv"%s", calc[1])argv[i]);
          break;}
          
        case 3:else{
          printListprintf(argc, argv"%s", " * "argv[i]);
          printf(" =s %d\n",+= applyOperatoratoi(argc, argv, calc[2])argv[i]);
          break;
          }
        case 4: //Divides just the first two args.
          printfif("%s / %s",i argv[1],== argv[2]argc-1);
          printf(" = %f\n", divi(strtol(argv[1], NULL, 0), strtol(argv[2],%c NULL", 0))sign);
          break;
          break;
        
        case 5: //Mods just the first two args.
          printf("%s mod %s", argv[1], argv[2]);else
          printf(" = %d\n", mod(strtol(argv[1], NULL, 0), strtol(argv[2],%c NULL", 0))sign);
          break;
          
        case 6:}
          rev(argc,argv);
        //Repeat for break;subtract
          
       //Print default:total
          printf("Enter valid option\n");
          break;
      }
    }

   "%d\n", exit(EXIT_SUCCESSs);
  }

  exit(EXIT_FAILURE);
}
```

But that seems like just making 1 function larger without really optimizing anything.

Does anyone have any suggestions or helpful advice for reducing the redundancy with add/sub (if its even possible)? Its not entirely necessary, but I'd appreciate any assistance.

EDIT: removed alternative implementation that wasn't much better.

Does anyone have any suggestions or helpful advice for reducing the redundancy with add/sub (if its even possible)? Its not entirely necessary, but I'd appreciate any assistance.

EDIT: Updated semi-improved code, now with more functionality:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define min(a, b) ((a) < (b) ? (a) : (b))
#define maxItems 15

typedef struct _Menu {
  int count;
  char *items[maxItems];
} Menu;

char *choices[] = {"Exit", "Addition", "Subtraction", "Multiplication", "Division", "Modulo", "Reverse Input"};
int count = sizeof(choices)/sizeof(choices[0]);

int printMenu(const Menu *menu){
  int ch;
  printf("\n");
  for (int i=0; i<menu->count; i++) 
    printf("%d. %s\n", i, menu->items[i]);

  printf("\nMenu Item: ");
  scanf("%d",&ch);
  return ch;
}

void strrev(char *str){

    if (str == 0)
      return;

    if (*str == 0)
      return;

    /* get range */
    char *start = str;
    char *end = start + strlen(str) - 1; /* -1 for \0 */
    char temp;

    /* reverse */
    while (end > start){
      /* swap */
      temp = *start;
      *start = *end;
      *end = temp;

      /* move */
      ++start;
      --end;
    }
}

void rev(int argc, char **argv){
  for (int i = argc-1; i > 0; --i){
    strrev(argv[i]);
    printf("%s ", argv[i]);
  }
  
  printf("\n");
}

int add(int a, int b){
  return a+b;
}

int sub(int a, int b){
  return a-b;
}

int mult(int a, int b){
  return a*b;
}

float divi(int a, int b){
  return a/b;
}

int mod(int a, int b){
  return a%b;
}

int applyOperator(int argc, char **argv, int (*op)(int, int)) {
  int retval = strtol(argv[0], NULL, 0);

  for (int i = 1; i < argc; ++i) {
    retval = op(retval, strtol(argv[i], NULL, 0));
  }

  return retval;
}

void printList(int argc, char **argv, const char *sep) {
  printf("%s", argv[1]);
  
  for (int i = 2; i < argc; ++i) {
      printf("%s%s", sep, argv[i]);
  }
}

//Attempting implementation of function dispatch table
int (*calc[])(int, int) = {add, sub, mult};

int main(int argc,char** argv){
 
  Menu menu;
  menu.count = min(count, maxItems);
  
  for (int i=0; i < menu.count; i++)
    menu.items[i] = choices[i];

  if(argc < 3)
    fprintf(stderr, "You must enter at least two arguments.\n");

  else if(argc > 16)
    fprintf(stderr, "You cannot enter more than 15 arguments.\n");

  else{

    int ch=1;
    while(ch!=0){   
      ch = printMenu(&menu);

      switch(ch){
        case 0:
          exit(0);
          break;

        case 1:
          printList(argc, argv, " + ");
          printf(" = %d\n", applyOperator(argc, argv, calc[0]));
          break;
        
        case 2:
          printList(argc, argv, " - ");
          printf(" = %d\n", applyOperator(argc, argv, calc[1]));
          break;
          
        case 3:
          printList(argc, argv, " * ");
          printf(" = %d\n", applyOperator(argc, argv, calc[2]));
          break;
          
        case 4: //Divides just the first two args.
          printf("%s / %s", argv[1], argv[2]);
          printf(" = %f\n", divi(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0)));
          break;
          break;
        
        case 5: //Mods just the first two args.
          printf("%s mod %s", argv[1], argv[2]);
          printf(" = %d\n", mod(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0)));
          break;
          
        case 6:
          rev(argc,argv);
          break;
          
        default:
          printf("Enter valid option\n");
          break;
      }
    }

    exit(EXIT_SUCCESS);
  }

  exit(EXIT_FAILURE);
}
```

Example:

void calc(int argc, char **argv, int op){

  int i = 1, s = 0, x = 0;
  char sign = (op == 1) ? '+' :  '-';

  if(isHex(argv[i], strlen(argv[i])))
    s = (x =convertHex(argv[i], strlen(argv[i])));

  else
    s = atoi(argv[i]); 

  for(i = 2;i<argc;i++){
 
    //Add
    if(op == 1){
      if(isHex(argv[i], strlen(argv[i]))){
        s += (x = convertHex(argv[i], strlen(argv[i])));
        printf("%s", argv[i]);
      }

      else{
        printf("%s", argv[i]);
        s += atoi(argv[i]);
      }

      if(i == argc-1)
        printf(" %c ", sign);
      else
        printf(" %c ", sign);
    }

    //Repeat for subtract

    //Print total
    printf("%d\n", s);
  }
}

But that seems like just making 1 function larger without really optimizing anything.

Does anyone have any suggestions or helpful advice for reducing the redundancy with add/sub (if its even possible)? Its not entirely necessary, but I'd appreciate any assistance.

Updated with improved code, removed poor alternative approach that was scraped.
Source Link

Example:EDIT: removed alternative implementation that wasn't much better.

void calc(int argc, char **argv, int op){

  int i = 1, s = 0, x = 0;
  char sign = (op == 1) ? '+' :  '-';

  if(isHex(argv[i], strlen(argv[i])))
    s = (x =convertHex(argv[i], strlen(argv[i])));

  else
    s = atoi(argv[i]); 

  for(i = 2;i<argc;i++){

    //Add
    if(op == 1){
      if(isHex(argv[i], strlen(argv[i]))){
        s += (x = convertHex(argv[i], strlen(argv[i])));
        printf("%s", argv[i]);
      }

      else{
        printf("%s", argv[i]);
        s += atoi(argv[i]);
      }

      if(i == argc-1)
        printf(" %c ", sign);
      else
        printf(" %c ", sign);
    }

    //Repeat for subtract

    //Print total
    printf("%d\n", s);
  }
}

Does anyone have any suggestions or helpful advice for reducing the redundancy with add/sub (if its even possible)? Its not entirely necessary, but I'd appreciate any assistance.

But that seems like just making 1 function larger without really optimizing anything.EDIT: Updated semi-improved code, now with more functionality:

Does anyone have any suggestions or helpful advice for reducing the redundancy with add/sub (if its even possible)? Its not entirely necessary, but I'd appreciate any assistance.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define min(a, b) ((a) < (b) ? (a) : (b))
#define maxItems 15

typedef struct _Menu {
  int count;
  char *items[maxItems];
} Menu;

char *choices[] = {"Exit", "Addition", "Subtraction", "Multiplication", "Division", "Modulo", "Reverse Input"};
int count = sizeof(choices)/sizeof(choices[0]);

int printMenu(const Menu *menu){
  int ch;
  printf("\n");
  for (int i=0; i<menu->count; i++) 
    printf("%d. %s\n", i, menu->items[i]);

  printf("\nMenu Item: ");
  scanf("%d",&ch);
  return ch;
}

void strrev(char *str){

    if (str == 0)
      return;

    if (*str == 0)
      return;

    /* get range */
    char *start = str;
    char *end = start + strlen(str) - 1; /* -1 for \0 */
    char temp;

    /* reverse */
    while (end > start){
      /* swap */
      temp = *start;
      *start = *end;
      *end = temp;

      /* move */
      ++start;
      --end;
    }
}

void rev(int argc, char **argv){
  for (int i = argc-1; i > 0; --i){
    strrev(argv[i]);
    printf("%s ", argv[i]);
  }
  
  printf("\n");
}

int add(int a, int b){
  return a+b;
}

int sub(int a, int b){
  return a-b;
}

int mult(int a, int b){
  return a*b;
}

float divi(int a, int b){
  return a/b;
}

int mod(int a, int b){
  return a%b;
}

int applyOperator(int argc, char **argv, int (*op)(int, int)) {
  int retval = strtol(argv[0], NULL, 0);

  for (int i = 1; i < argc; ++i) {
    retval = op(retval, strtol(argv[i], NULL, 0));
  }

  return retval;
}

void printList(int argc, char **argv, const char *sep) {
  printf("%s", argv[1]);
  
  for (int i = 2; i < argc; ++i) {
      printf("%s%s", sep, argv[i]);
  }
}

//Attempting implementation of function dispatch table
int (*calc[])(int, int) = {add, sub, mult};

int main(int argc,char** argv){

  Menu menu;
  menu.count = min(count, maxItems);
  
  for (int i=0; i < menu.count; i++)
    menu.items[i] = choices[i];

  if(argc < 3)
    fprintf(stderr, "You must enter at least two arguments.\n");

  else if(argc > 16)
    fprintf(stderr, "You cannot enter more than 15 arguments.\n");

  else{

    int ch=1;
    while(ch!=0){   
      ch = printMenu(&menu);

      switch(ch){
        case 0:
          exit(0);
          break;

        case 1:
          printList(argc, argv, " + ");
          printf(" = %d\n", applyOperator(argc, argv, calc[0]));
          break;
        
        case 2:
          printList(argc, argv, " - ");
          printf(" = %d\n", applyOperator(argc, argv, calc[1]));
          break;
          
        case 3:
          printList(argc, argv, " * ");
          printf(" = %d\n", applyOperator(argc, argv, calc[2]));
          break;
          
        case 4: //Divides just the first two args.
          printf("%s / %s", argv[1], argv[2]);
          printf(" = %f\n", divi(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0)));
          break;
          break;
        
        case 5: //Mods just the first two args.
          printf("%s mod %s", argv[1], argv[2]);
          printf(" = %d\n", mod(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0)));
          break;
          
        case 6:
          rev(argc,argv);
          break;
          
        default:
          printf("Enter valid option\n");
          break;
      }
    }

    exit(EXIT_SUCCESS);
  }

  exit(EXIT_FAILURE);
}
```

Example:

void calc(int argc, char **argv, int op){

  int i = 1, s = 0, x = 0;
  char sign = (op == 1) ? '+' :  '-';

  if(isHex(argv[i], strlen(argv[i])))
    s = (x =convertHex(argv[i], strlen(argv[i])));

  else
    s = atoi(argv[i]); 

  for(i = 2;i<argc;i++){

    //Add
    if(op == 1){
      if(isHex(argv[i], strlen(argv[i]))){
        s += (x = convertHex(argv[i], strlen(argv[i])));
        printf("%s", argv[i]);
      }

      else{
        printf("%s", argv[i]);
        s += atoi(argv[i]);
      }

      if(i == argc-1)
        printf(" %c ", sign);
      else
        printf(" %c ", sign);
    }

    //Repeat for subtract

    //Print total
    printf("%d\n", s);
  }
}

But that seems like just making 1 function larger without really optimizing anything.

Does anyone have any suggestions or helpful advice for reducing the redundancy with add/sub (if its even possible)? Its not entirely necessary, but I'd appreciate any assistance.

EDIT: removed alternative implementation that wasn't much better.

Does anyone have any suggestions or helpful advice for reducing the redundancy with add/sub (if its even possible)? Its not entirely necessary, but I'd appreciate any assistance.

EDIT: Updated semi-improved code, now with more functionality:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define min(a, b) ((a) < (b) ? (a) : (b))
#define maxItems 15

typedef struct _Menu {
  int count;
  char *items[maxItems];
} Menu;

char *choices[] = {"Exit", "Addition", "Subtraction", "Multiplication", "Division", "Modulo", "Reverse Input"};
int count = sizeof(choices)/sizeof(choices[0]);

int printMenu(const Menu *menu){
  int ch;
  printf("\n");
  for (int i=0; i<menu->count; i++) 
    printf("%d. %s\n", i, menu->items[i]);

  printf("\nMenu Item: ");
  scanf("%d",&ch);
  return ch;
}

void strrev(char *str){

    if (str == 0)
      return;

    if (*str == 0)
      return;

    /* get range */
    char *start = str;
    char *end = start + strlen(str) - 1; /* -1 for \0 */
    char temp;

    /* reverse */
    while (end > start){
      /* swap */
      temp = *start;
      *start = *end;
      *end = temp;

      /* move */
      ++start;
      --end;
    }
}

void rev(int argc, char **argv){
  for (int i = argc-1; i > 0; --i){
    strrev(argv[i]);
    printf("%s ", argv[i]);
  }
  
  printf("\n");
}

int add(int a, int b){
  return a+b;
}

int sub(int a, int b){
  return a-b;
}

int mult(int a, int b){
  return a*b;
}

float divi(int a, int b){
  return a/b;
}

int mod(int a, int b){
  return a%b;
}

int applyOperator(int argc, char **argv, int (*op)(int, int)) {
  int retval = strtol(argv[0], NULL, 0);

  for (int i = 1; i < argc; ++i) {
    retval = op(retval, strtol(argv[i], NULL, 0));
  }

  return retval;
}

void printList(int argc, char **argv, const char *sep) {
  printf("%s", argv[1]);
  
  for (int i = 2; i < argc; ++i) {
      printf("%s%s", sep, argv[i]);
  }
}

//Attempting implementation of function dispatch table
int (*calc[])(int, int) = {add, sub, mult};

int main(int argc,char** argv){

  Menu menu;
  menu.count = min(count, maxItems);
  
  for (int i=0; i < menu.count; i++)
    menu.items[i] = choices[i];

  if(argc < 3)
    fprintf(stderr, "You must enter at least two arguments.\n");

  else if(argc > 16)
    fprintf(stderr, "You cannot enter more than 15 arguments.\n");

  else{

    int ch=1;
    while(ch!=0){   
      ch = printMenu(&menu);

      switch(ch){
        case 0:
          exit(0);
          break;

        case 1:
          printList(argc, argv, " + ");
          printf(" = %d\n", applyOperator(argc, argv, calc[0]));
          break;
        
        case 2:
          printList(argc, argv, " - ");
          printf(" = %d\n", applyOperator(argc, argv, calc[1]));
          break;
          
        case 3:
          printList(argc, argv, " * ");
          printf(" = %d\n", applyOperator(argc, argv, calc[2]));
          break;
          
        case 4: //Divides just the first two args.
          printf("%s / %s", argv[1], argv[2]);
          printf(" = %f\n", divi(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0)));
          break;
          break;
        
        case 5: //Mods just the first two args.
          printf("%s mod %s", argv[1], argv[2]);
          printf(" = %d\n", mod(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0)));
          break;
          
        case 6:
          rev(argc,argv);
          break;
          
        default:
          printf("Enter valid option\n");
          break;
      }
    }

    exit(EXIT_SUCCESS);
  }

  exit(EXIT_FAILURE);
}
```
Tweeted twitter.com/StackCodeReview/status/1326041904803434501
added 196 characters in body
Source Link

I'm working on a program that adds or subtracts up to 15 decimal or hexadecimal numbers from the command line. I You run the program with the arguments and then choose the option from a menu. I.e.:./main 5 10 15 20 will take in those four arguments and allow you to either add or subtract.

I have a working program, but I am trying to optimize it to reduce some redundancy. Basically my add and subtract functions are identical other than some sign switches, and I feel like there might be a better way. Here is what I have so far (the program can accept decimal input, or hex input formatted with a preceding 0x, which is why there are a sections dealing with those conversions):

I'm working on a program that adds or subtracts up to 15 decimal numbers from the command line. I have a working program, but I am trying to optimize it to reduce some redundancy. Basically my add and subtract functions are identical other than some sign switches, and I feel like there might be a better way. Here is what I have so far (the program can accept decimal input, or hex input formatted with a preceding 0x, which is why there are a sections dealing with those conversions):

I'm working on a program that adds or subtracts up to 15 decimal or hexadecimal numbers from the command line. You run the program with the arguments and then choose the option from a menu. I.e.:./main 5 10 15 20 will take in those four arguments and allow you to either add or subtract.

I have a working program, but I am trying to optimize it to reduce some redundancy. Basically my add and subtract functions are identical other than some sign switches, and I feel like there might be a better way. Here is what I have so far (the program can accept decimal input, or hex input formatted with a preceding 0x, which is why there are a sections dealing with those conversions):

edited title
Link
Loading
Source Link
Loading