3
\$\begingroup\$

Indian Currency format is 12345 → "12,345" (for odd length) and 123456 → "1,23,456" (for even length). I have included all possibilities such as

  1. Minus sign: "-12,345"
  2. Decimal Point: "-12,345.345" or "12,345.123"
  3. Zero Condition 000000.123 → "0.123"
  4. Minus and Zero Condition '-000000.123' -> "-0.123"
int main()
{
    char        currency[20];
    char        *tmpCurrency=NULL;
    int         length = 0;
    int         j = 0, commas = 0,n=0;
    int  i = 0, cnt = 0;
    char        *s=NULL;
    int        signCount=0;
    puts("Enter the Currency");
    gets_s(currency,20);

    n = strspn(currency+1, "0");                            //to find number of zeros present in the array. 

    if (currency[n] == '.' || currency[n]=='\0' )         //for Condtion like 0000000 or 000000.123 so as to maintain one zero so that o/p will be 0 or 0.123
    {

        memmove(currency, currency + n, strlen(currency));
    }
    else
    {
        memmove(currency, currency + n, strlen(currency));
    }

signCount==1?currency[0]='-':NULL;

    (s = strchr(currency, '.')) ? (length = s - currency) : (length = strlen(currency));   // Considering decimal Point and restricing to Put commas after decimal Point


    if (length>3)
    commas = (length / 2) - 1;                                                            // No of Commas to put 

    tmpCurrency = (char*)malloc((length + commas+1) * (sizeof(char*))); 

    while (currency[i] != '\0')
    {
        if (cnt == commas)   //maintaining count to check how many commas have been put in the character array
        {
            tmpCurrency[j] = currency[i];
            i++;
            j++;
            continue;
        }
          if (length % 2 == 0)                            //When length is even comma comes after 1 digit eg 1,23,456. so what i have done adjusting length ann checking when it is becoming even and putting comma.
        {
            tmpCurrency[j] = currency[i];
            if (currency[i] != '-' && currency[i+1]!='.')
            {
               tmpCurrency[j = j + 1] = ',';
            }
            i++;
            j++;
            length = length - 1;
            cnt++;
         }
        if (length % 2 != 0)         //for odd length putting one element in tmpCurrency and then subtracting length to make it even. 
        {
            tmpCurrency[j] = currency[i];
            i++;
            j++;
            length = length - 1;
        }
    }

    tmpCurrency[j] = '\0';
    strcpy_s(currency,20, tmpCurrency);
    puts(currency);
    free(tmpCurrency);

    return 0;
}
\$\endgroup\$
8
  • \$\begingroup\$ Bitwise operator will help to Optimize the code? \$\endgroup\$
    – Devious
    May 14, 2017 at 15:56
  • 2
    \$\begingroup\$ gets_s(currency) doesn't look right (gets_s requires 2 arguments). Please double check. \$\endgroup\$
    – vnp
    May 14, 2017 at 17:52
  • \$\begingroup\$ Yes it takes size as first parameter.I will be implementing in CGI so it won't be a Problem. \$\endgroup\$
    – Devious
    May 15, 2017 at 4:30
  • 2
    \$\begingroup\$ Please provide working code (at very least code that compiles). There are multiple omissions here (get_s, signCount, include files, just to mention few) \$\endgroup\$ May 15, 2017 at 9:24
  • \$\begingroup\$ This Code is working.You can compile it. Include header files it will be working \$\endgroup\$
    – Devious
    May 15, 2017 at 14:36

1 Answer 1

3
\$\begingroup\$
  1. Allocation woes. char *tmpCurrency needs enough memory for a null character terminated string. This implies a +1 to the length + commas addition. The cast of malloc() is not needed. Multiplying by the size of a pointer sizeof(char*) is wrong. It should be by the size of an element of tmpCurrency, which is a char. length,commas should be size_t rather than int, but that make s little difference with small strings.

    // tmpCurrency = (char*) malloc((length + commas) * (sizeof(char*)));
    tmpCurrency = malloc(sizeof *tmpCurrency * (length + commas + 1));
    
  2. Separate out functional code from the test driver. I'd expect some stand-alone function Devious_ICF(char *dest, const char *src) and then code in main() testing it.

  3. Questionable space size and incorrect use of gets_s(char *s, rsize_t n). Avoid coding naked magic numbers like 20

    // char        currency[20];
    // gets_s(currency);
    
    #define CURRENCY_SIZE 20
    ...
    char currency[CURRENCY_SIZE];
    gets_s(currency, sizeof currency);
    
  4. stdout is not certainly output as a prompt before asking for input. To maintain portability, flush.

    puts("Enter the Currency");
    fflush(stdout);  // add
    gets_s(...);
    
  5. Curious use of static. static not needed here.

    // static int  i = 0, cnt = 0;
    int  i = 0, cnt = 0;
    
  6. Accessing code outside array bounds.

    // memmove(currency, currency + n, strlen(currency));
    memmove(currency, currency + n, strlen(currency) - n);
    currency[n] = '\0';
    
  7. Use of ?: does not certainly use a consistent type as the types of currency[0]='-' and NULL may differ. An if() would be better anyways.

    // signCount==1?currency[0]='-':NULL;
    if (signCount==1) {
      currency[0] = '-';
    }
    
  8. Format to presentation width. Use an auto formatter. Weak formatting employed significantly detracts from code's presentation.

              if (length % 2 == 0)                            //When length is even comma comes after 1 digit eg 1,23,456. so what i have done adjusting length ann checking when it is becoming even and putting comma.
    

versus

          // When length is even, comma comes after 1 digit e.g. 1,23,456. 
          //   so what i have done adjusting length and checking when it is 
          //   becoming even and putting comma.
          if (length % 2 == 0) 
  1. Incorrect use of errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2);. Missing parameter.

    strcpy_s(currency, tmpCurrency);`
    
  2. Missing #include headers.

  3. Overall - approach used is excessively complex.

Given above issues that a compiler should have reported, it implies compilation is not done with warning fully enabled or code is using non-standard C. Recommend fully enabling all warnings.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.