2014-10-07 2 views
-4

Предположим, что у меня есть вход 3.50 (строка), как его разобрать, чтобы он хранился как 3 доллара и 50 центов. Доллары и центы являются целыми числами, и atoi не допускается.Как разбирать доллары и центы в C

Я имею это в виду, но, видимо, он не работает в C (при условии, токена 3,50):

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

Спасибо!

+1

Пожалуйста, не конвертируйте значение в 'float'. Люди смеются над ошибками округления. –

+5

Если 'atoi' не разрешено, нужно задаться вопросом, разрешена ли * любая функция библиотеки. Возможно, все дело в том, чтобы разобрать строку самостоятельно, по одному персонажу за раз. – user3386109

+0

Используйте 'sprintf' вместо' atoi'. – ymn

ответ

0

Вы хотите изменить их, чтобы обработать недопустимый ввод грациозно, но эти функции будут работать с действительным ввода:

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; 
} 
+0

хотите добавить комментарий. – Teddy

+0

Добавлены комментарии, объясняющие мой код. :) –

0

Предполагая центы вы после всего 2 десятичных знаков в длине и маркер double, вычитать доллары из маркеров и умножить на 100.

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

EDIT: Как из комментария, с token существами char *:

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

EDIT 2: Как из комментария, без itoa() и sscanf():

Выполните следующую функцию, как описано here. Затем можно использовать:

double amount=parseFloat(token); 
dollars=int(amount); 
cents=int((amount-dollars)*100.); 
+1

токен - это строка (указатель на символ). – Teddy

+0

Я вижу, тогда нам нужно использовать другой подход. См. Измененный ответ. – DoubleYou

+0

мои плохие, atoi и sscanf не допускаются. – Teddy

1

вы можете использовать sscanf

sscanf(stringWhereDollarCentValueIsStored , "%d.%d" , &dollars , &cents); 
+0

Не могу заставить я использовать это в функции, где я читаю данные из файла. – Teddy

+0

@ Тедди, как это делает этот ответ недействительным для вашей проблемы? –

+0

вы можете использовать его всякий раз, когда вы хотите, чтобы он ни на что не повлиял, но две переменные 'dollars' и' cents' –

2

Если вы хотите катить свои string до int парсер ...

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; 
} 
+0

Ах, да, этот ответ намного безопаснее моего: P –

+2

@Govind Parmar Спасибо, но у него есть эти недостатки (все легко изменить): нет обнаружения переполнения, обнаружения пустой строки, отрицательных значений центов (вид глупый, чтобы иметь «123.-45»), предел центов ровно на 2 цифры, дополнительные данные после центов, что приводит к потреблению белого пространства.OP может добавлять по желанию. – chux

Смежные вопросы