# Indian currency format using C [closed]

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;
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='-':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;
}

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

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;
// 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");
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='-' and NULL may differ. An if() would be better anyways.

// signCount==1?currency='-':NULL;
if (signCount==1) {
currency = '-';
}

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.