2016-08-11 4 views
3

Пытается внедрить очень простой конвертер Roman Numeral в Decimal, но не может показаться, что программа возвращает -1, если в строке находятся какие-либо не-римские цифры. Это то, что у меня есть до сих пор.Roman Numeral To Decimal

#include <stdio.h> 
#include <ctype.h> 

int convertFromRoman(const char *s) 
{ 

int i = 0; 
int total = 0; 

while (s[i] != '\0') { 

    if (isalpha(s[i]) == 0) { 
     return -1; 
    } 

    if (toupper(s[i]) == 'I') { 
     total += 1; 
    } 

    if (toupper(s[i]) == 'V') { 
     total += 5; 
    } 

    if (toupper(s[i]) == 'X') { 
     total += 10; 
    } 

    if (toupper(s[i]) == 'L') { 
     total += 50; 
    } 

    if (toupper(s[i]) == 'C') { 
     total += 100; 
    } 

    if (toupper(s[i]) == 'D') { 
     total += 500; 
    } 

    if (toupper(s[i]) == 'M') { 
     total += 1000; 
    } else { 
     return -1; 
    } 

    i++; 
} 

if (total == 0) { 
    return -1; 
} 

return total; 
} 



int main() 
{ 
    printf("%d\n", convertFromRoman("XVII")); 
    printf("%d\n", convertFromRoman("ABC")); 
} 

Первый должен возвращать 17, а второй должен возвращать -1. Однако оба они возвращают -1, но если я удалю оператор else, первый возвращает 17, а второй возвращает 100.

Любая помощь приветствуется.

+1

Мы не решим домашнее задание для вас. Вероятно, не очень хорошая идея, чтобы ваша первая строка была «// Homework» –

+3

Спасибо за ваш комментарий @CharlieFish. Не просил никого решить его! Был просто нужен совет по поводу того, что мне не хватало/сослался на какую-то документацию. Просто поставьте домашнее задание, чтобы я не получил полного ответа, потому что это не лучший способ узнать! – Mikey

+4

использовать 'else if'. (но ваша логика имеет неправильный результат «IV») – BLUEPIXY

ответ

4

Изменить if()if()if()else в if()else if()else if()else

if (toupper(s[i]) == 'I') { 
     total += 1; 
    } 

    else if (toupper(s[i]) == 'V') { 
     total += 5; 
    } 

    else if (toupper(s[i]) == 'X') { 
     total += 10; 
    } 

    .... 

    else if (toupper(s[i]) == 'M') { 
     total += 1000; 
    } else { 
     return -1; 
    } 
+0

Или, если вы хотите ОП, вы можете использовать 'switch (toupper (s [i]))', чтобы сделать что-то немного проще. – RastaJedi

+1

@RastaJedi Есть _many_ потенциальные улучшения кода OP. Для меня я сделал бы что-нибудь по [@Tibrogargan] (http://stackoverflow.com/a/38886941/2410359). У ОП возникли проблемы с 'if'' else if'' else', поэтому в ответах основное внимание уделяется этому. BTW это должно быть 'switch (toupper ((unsigned char) s [i]))', чтобы избежать UB should 's [i]' быть отрицательным. – chux

+0

Да, я просто смотрел на его ответ; это довольно изящно. Это полезно знать ... Я только быстро открыл человека и увидел прототип как «int toupper (int c);», но я думаю, что многие функции, которые работают с символами, указывают их как «int», они. – RastaJedi

2

Не совсем ответ, просто немного веселья/альтернативный способ смотреть на проблему. Он решает проблему, если вы не планируете заказывать только добавление значений «цифр».

char *romanNumerals = "IVXLCDM"; 
int values[] = { 1, 5, 10, 50, 100, 500, 1000 }; 

int convertFromRoman(const char *s) { 
    int val = 0; 
    for (int i = 0; s[i]; i++) { 
     char *idx; 
     if (NULL == (idx = strchr(romanNumerals, toupper(s[i])))) { 
      return -1; 
     } 
     val += values[idx - romanNumerals]; 
    } 
    return val; 
}