-4

Suppose I have an input of 3.50 (string), how do I parse it so that it gets stored as 3 dollars and 50 cents. Dollars and cents are both integers, and atoi is not allowed.

I have this in mind but apparently it doesn't work in C (assuming token is 3.50):

dollars = int(token); /* dollars is 3 */
cents = atoi(token) - dollars; /* atoi is not allowed but I can't think of anything else */

Thanks!

Teddy
  • 19
  • 1
  • 5
  • 1
    Please do not convert the value into a `float`. People get funny over rounding errors – Ed Heal Oct 07 '14 at 03:03
  • 5
    If `atoi` is not allowed, one has to wonder whether *any* library function is allowed. Perhaps the whole point is to parse the string yourself, one character at a time. – user3386109 Oct 07 '14 at 03:10
  • Use `sprintf` instead of `atoi`. – ymn Oct 07 '14 at 03:14
  • 1
    -1 for these arbitrary requirements to shun standard library, stated in comments to answers. You should do your own homework. It will be better for you. – David Heffernan Oct 07 '14 at 03:58

4 Answers4

2

Should you want to roll your own string to int parser ...

int parse_int(char **s) {
  char sign = **s;
  if (sign == '-' || sign == '+') {
    (*s)++;
  }
  int result = 0;
  unsigned char ch;
  while (isdigit(ch = **s)) {
    (*s)++;
     // By accumulating the int on the negative side, we can parse INT_MIN
    result = result * 10 + '0' - ch;
  }

  if (sign != '-') result = -result;
  return result;
}


void parse_dollars_cents(char **s, int *dollar, int *cent) {
  *dollar = parse_int(s);
  if (**s == '.') {
    (*s)++;
    *cent = parse_int(s);
  } else {
    *cent = 0;
  }
}


int main(void) {
  char buf[100];
  fgets(buf, sizeof buf, stdin);
  int dollar, cent;
  char *s = buf;
  parse_dollars_cents(&s, &dollar, &cent);
  printf("$%d.%02d\n", dollar, cent);
  return 0;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Ah, yes, this answer is a lot safer than mine :P – Govind Parmar Oct 07 '14 at 03:38
  • 2
    @Govind Parmar Thanks, but it has these shortcomings (all easy to amend): no overflow detection, empty string detection, negative values of cents (kind of silly to have "123.-45"), limit cents to exactly 2 digits, extra data after cents, leading white-space consumption. OP can add as desired. – chux - Reinstate Monica Oct 07 '14 at 03:42
1

you can use sscanf

sscanf(stringWhereDollarCentValueIsStored , "%d.%d" , &dollars , &cents);
Farouq Jouti
  • 1,657
  • 9
  • 15
0

Assuming the cents you're after is only 2 decimals in length and token is double, subtract the dollars from the token and multiply by 100.

dollars=int(token);
token-=dollars;
cents=int(token*100.);

EDIT: As from the comment, with token being a char *:

int dollars, cents;
sscanf(token,"%d.%d",&dollars,&cents);

EDIT 2: As from the comment, without itoa() and sscanf():

Implement the following function as described here. Then use it:

double amount=parseFloat(token);
dollars=int(amount);
cents=int((amount-dollars)*100.);
Community
  • 1
  • 1
DoubleYou
  • 1,057
  • 11
  • 25
0

You'll want to modify these to handle invalid input gracefully but these functions will work with valid input:

int get_dollars(char *str)
{
    int i = 0;
    int accum = 0;

    // While the current character is neither the null-terminator nor a '.' character
    while(str[i]&&str[i]!='.')
    {
        // Shift any previously accumulated values up one place-value by multiplying it by 10
        accum *= 10;
        // Add the numeric value of the character representation of the digit in str[i] to accum
        // (('0'-'9')-0x30=integer value 0-9)
        accum+=str[i]-0x30;
        // Increment the loop counter
        i++;
    }
    // Return the result
    return accum;
}

int get_cents(char *str)
{
    int i = 0; 
    int accum = 0;
    int start_pos = 0;
    // Get the location of the '.' character so we know where the cent portion begins at
    while(str[i]&&str[i]!='.') {i++; start_pos++; }
    i = start_pos+1;
    // Same algorithm as get_dollars, except starting after the '.' rather than before
    while(str[i])
    {
        accum *= 10;
        accum += str[i]-0x30;
        i++;
    }
    return accum;
}
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85