Sky wifibrand
Sky wifibrand

Reputation: 109

Alternative way for if-statement or switch statement with a lot of conditions

In this code, I am getting an input from the user to enter a number(s). After giving some number(s), the desired message will be printed according to that particular number.

My question is that if the numbers are not exactly sure as in this case then how can I put if-statement/switch in a short way. Because for example, if I entered 10,000 then I have to write if-statements/switch 10,000 times and this is not a good way.

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

int main(){
  int i;
  printf("Enter a number: ");
  // fgets(i, sizeof(i), stdin);
  scanf("%d", &i);

  if(i == 1){
    printf("one");
  }
  else if(i == 2){
    printf("two");
  }
  else{
    printf("%d\n", i);
  }

  return 0;
}

Upvotes: 0

Views: 125

Answers (4)

Craig Estey
Craig Estey

Reputation: 33601

Here's a version that can take 64 bit numbers:

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

int opt_d;
int opt_f;

typedef long long val_t;

#define ARRAY_SIZE(_arr) \
    sizeof(_arr) / sizeof(_arr[0])

char *ones[] = {
    NULL,
    "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"
};

char *tens[] = {
    NULL,
    "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty",
    "ninety"
};

char *teens[] = {
    NULL,
#if 0
    "ten",
#endif
    "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen",
    "seventeen", "eighteen", "nineteen"
};

const char *places[] = {
    //NULL,
    //NULL,
#if 0
    "hundred",
#else
    NULL,
#endif
    "thousand",
    "million",
    "trillion",
    "quadrillion",
#if 0
    "quintillion",
#endif
#if 0
    "sextillion", "septillion", "octillion", "nonillion", "decillion",
    "undecillion", "duodecillion", "tredecillion", "quatttuor-decillion",
    "quindecillion", "sexdecillion", "septen-decillion", "octodecillion"
#endif
};

#define BUFWID  1000

char *odst;
char obuf[BUFWID];
const char *curplace;

#if defined(DEBUG) || defined(_USE_ZPRT_)
#define dbgprt(_fmt...) \
    do { \
        if (opt_d) \
            printf(_fmt); \
    } while (0)
#else
#define dbgprt(_fmt...) \
    do { } while (0)
#endif

val_t
ipow(int pow)
{
    val_t acc = 1;

    for (;  pow > 0;  --pow)
        acc *= 1000;

    return acc;
}

#define BUFMAX  20
char *
strbuf(void)
{
    static int bufidx = 0;
    static char bufpool[BUFMAX][BUFWID];

    char *buf = bufpool[bufidx];
    bufidx += 1;
    bufidx %= BUFMAX;

    *buf = 0;

    return buf;
}

const char *
show(val_t val)
{
    char *buf = strbuf();
    char tmp[100];

    int len = sprintf(tmp,"%lld",val);
    int off = len % 3;

    char *bp = buf;
    for (char *src = tmp;  *src != 0;  ++src, --off) {
        if (off == 0) {
            if (src > tmp)
                *bp++ = ',';
            off = 3;
        }
        *bp++ = *src;
    }
    *bp = 0;

    return buf;
}

void
append(const char *str)
{

    if (str != NULL) {
        if (odst > obuf)
            *odst++ = ' ';
        odst += sprintf(odst,"%s",str);
    }
}

val_t
digout(val_t bigval,int div,char **str,char *midplace)
{
    val_t cur = bigval / div;

    dbgprt("digout: ENTER bigval=%s div=%d cur=%s str='%s' midplace='%s'\n",
        show(bigval),div,show(cur),str[cur],midplace);

    if (cur != 0) {
        append(str[cur]);
        append(midplace);
    }

    bigval %= div;

    dbgprt("digout: EXIT bigval=%s\n",show(bigval));

    return bigval;
}

void
group(val_t bigval,int plidx)
{
    val_t cur;

    dbgprt("group: ENTER bigval=%s plidx=%d curplace='%s'\n",
        show(bigval),plidx,curplace);

    bigval = digout(bigval,100,ones,"hundred");
    if ((bigval > 10) && (bigval < 20))
        bigval = digout(bigval - 10,1,teens,NULL);
    else {
        bigval = digout(bigval,10,tens,NULL);
        bigval = digout(bigval,1,ones,NULL);
    }
    append(curplace);

    dbgprt("group: EXIT\n");
}

void
pretty(val_t origval)
{
    char tokbuf[BUFWID];
    char *cp;
    char *bp;
    int totlen = 0;

    sprintf(tokbuf,"%s -- %s",show(origval),obuf);

    bp = tokbuf;
    while (1) {
        cp = strtok(bp," ");
        if (cp == NULL)
            break;

        int toklen = strlen(cp);

        if ((totlen + 1 + toklen) >= 72) {
            printf("\n");
            totlen = 0;
            printf("+");
            totlen += 1;
        }

        if (bp == NULL) {
            printf(" ");
            totlen += 1;
        }

        printf("%s",cp);
        totlen += toklen;

        bp = NULL;
    }

    if (totlen > 0)
        printf("\n");
}

const char *
convert(val_t origval)
{
    val_t bigval = origval;

    odst = obuf;
    *odst = 0;

    int plidx = ARRAY_SIZE(places) - 1;
    dbgprt("convert: ENTER bigval=%s plidx=%d\n",show(bigval),plidx);

    while (bigval != 0) {
        val_t div = ipow(plidx);

        val_t cur = bigval / div;
        val_t dig = cur / 1000;

        curplace = places[plidx];
        dbgprt("convert: LOOP bigval=%s plidx=%d div=%s cur=%s dig=%s curplace='%s'\n",
            show(bigval),plidx,show(div),show(cur),show(dig),curplace);

        if (cur != 0) {
            group(cur,plidx);
            dbgprt("convert: OBUF obuf='%s'\n",obuf);
        }

        bigval %= div;
        plidx -= 1;
    }

    pretty(origval);

    dbgprt("convert: EXIT obuf='%s'\n",obuf);

    return obuf;
}

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

    --argc;
    ++argv;

    for (;  argc > 0;  --argc, ++argv) {
        cp = *argv;
        if (*cp != '-')
            break;

        cp += 2;
        switch (cp[-1]) {
        case 'd':
            opt_d = ! opt_d;
            break;

        case 'f':
            opt_f = ! opt_f;
            break;
        }
    }

    int dodiag = 1;
    for (;  argc > 0;  --argc, ++argv) {
        dodiag = 0;
        val_t val = strtoll(*argv,&cp,10);
        convert(val);
    }

    if (dodiag) {
        convert(1234);
        convert(117);
        convert(311);
        convert(412);
        convert(1234567);
        convert(12319678);
        convert(123456789);
        convert(12345678927594);
    }

    return 0;
}

Here's the program's default output:

1,234 -- one thousand two hundred thirty four
117 -- one hundred seventeen
311 -- three hundred eleven
412 -- four hundred twelve
1,234,567 -- one million two hundred thirty four thousand five hundred
+ sixty seven
12,319,678 -- twelve million three hundred nineteen thousand six
+ hundred seventy eight
123,456,789 -- one hundred twenty three million four hundred fifty six
+ thousand seven hundred eighty nine
12,345,678,927,594 -- twelve quadrillion three hundred forty five
+ trillion six hundred seventy eight million nine hundred twenty seven
+ thousand five hundred ninety four

Upvotes: 0

Pedro Perez
Pedro Perez

Reputation: 330

You need to decompose the number in powers of ten and print it. So, for example, for 3452 you will need to know is "3000" "400" "50" and "2".

You need to be careful with special cases from 11 to 19, because it is not "one and ten" but "eleven" all the way to 19, "nineteen", then it is regular.

#include <stdio.h>
#include <stdint.h>
#include <string.h>


int main(int argc, char**argv)
{
  uint16_t input_num=0;
  uint8_t units,tens,hundreds,thousands;
  char* unitsStr[]={"","one","two","three","four","five","six","seven","eight","nine","ten"};
  char* tensStr[]={"","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
  char* specialCaseStr[]={"","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eightteen","nineteen"};
  char finalString[128]={0};
  char tempStr[64]={0};

  printf("Please enter the number: ");
  scanf("%hd",&input_num);
  printf("\r\nEntered %d\r\n",input_num);

  units =      input_num % 10;
  tens =      (input_num / 10) % 10;
  hundreds =  (input_num / 100) % 10;
  thousands = (input_num / 1000) % 10;

  if(thousands > 0)
  {
    sprintf(tempStr,"%s thousand ",unitsStr[thousands]);
    strcat(finalString,tempStr);
  }

  if(hundreds > 0)
  {
    sprintf(tempStr,"%s hundred ",unitsStr[hundreds]);
    strcat(finalString,tempStr);
  }

  if((units+(tens*10)) >= 11 &&  (units+(tens*10)) <= 19)
  {
    sprintf(tempStr,"%s",specialCaseStr[units]);
    strcat(finalString,tempStr);
  }
  else
  {
    if(tens > 0)
    {
      sprintf(tempStr,"%s ",tensStr[hundreds]);
      strcat(finalString,tempStr);
    }
    if(units > 0)
    {
      sprintf(tempStr,"%s ",unitsStr[units]);
      strcat(finalString,tempStr);
    }
  }

  printf("%s\r\n",finalString);

  return 0;

}

It could be further optimized for memory usage, that is left as an exercise.

Upvotes: 1

alex01011
alex01011

Reputation: 1702

Couple of things you could do, first is an array of strings, arranged the right way, like so:

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

int main()
{
    int i;
    char *numbers[] = {"one", "two", "three"}; /* fill more numbers */

    printf("Enter a number: ");

    if (scanf("%d", &i) != 1)
    {
        exit(EXIT_FAILURE);
    }

    if (i - 1 >= 0)
    {
        puts(numbers[i - 1]);
    }
    else
    {
        fprintf(stderr, "Invalid input\n");
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}

I guess you could also have one conditional expression as well :

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

#define MAX_LEN 1000

int main()
{
    int i;

    printf("Enter a number: ");

    if (scanf("%d", &i) != 1)
    {
        exit(EXIT_FAILURE);
    }

    char buffer[MAX_LEN];

    snprintf(buffer,MAX_LEN,"%d",i); /* converting the int read into a string */

    printf("%s",(i == 1 ? "one" : i == 2 ? "two" : buffer));

    exit(EXIT_SUCCESS);
}

Upvotes: 0

ShellCode
ShellCode

Reputation: 1162

You could use an array to store your strings, but you have to make sure the chosen value does not go beyond the numbers of elements in your array :

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


int main(){
  const char *numbers[] = {"zero", "one", "two"};

  int i;
  printf("Enter a number: ");
  // fgets(i, sizeof(i), stdin);
  scanf("%d", &i);

  if(i >= 0 && i < sizeof numbers / sizeof *numbers){
    printf("%s\n", numbers[i]);
  }
  else{
    printf("%d\n", i);
  }

  return 0;
}

Upvotes: 0

Related Questions