2017-01-14 22 views
-3

Я хочу взять строку, состоящую только из чисел и арифметических операторов. Затем решим их алгебраически. например Пользователь вводит в качестве строки = «45 - 98 + 656» и выводит на выходе как «603» целое число. Вот мой кодC программа для преобразования строки в целое число и решает их алгебраически

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

int main(void){ 

    scanf(%s, &S); 
    int sum = 0; 
    int a; 
    for (int i = 0; i < strlen(S); i++) { 
     if (S[i] == ' ') { 
      continue; 
     } else 
     if (S[i] != ' ') { 
      if (isdigit(S[i])) { 
       a = atoi(&S[i]); 
      } else 
      if (!isdigit(S[i])) { 
       if (S[i] == '+') {      
        S[i] = S[i + 1]; 
        sum = (sum + a); 
       } else 
       if (S[i] == '-') {   
        S[i] = S[i + 1]; 
        sum = (sum - a); 
       } else { 
        sum = a; 
       } 
      } 
     }                    
    } 
    printf("%d", sum); 
} 
+4

Итак, в чем ваш вопрос? – GoodDeeds

+0

Я хочу добавить эту последовательность чисел в строку. Так же, как мы делаем это в калькуляторе. – manish

+2

Это не вопрос – csmckelvey

ответ

2

Ваш код содержит ошибки синтаксиса.

  • Вы забыли " вокруг %s
  • вы не объявлял S

Вот простое решение:

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

int main(void) { 
    char buf[200]; 

    if (fgets(buf, sizeof buf, stdin)) { 
     long sum = 0; 

     /* remove all white space */ 
     for (int i = j = 0, len = strlen(buf); i <= len; i++) { 
      if (!isspace((unsigned char)buf[i])) 
       buf[j++] = buf[i]; 
     } 
     /* parse the expression */ 
     for (char *p = buf, *q;;) { 
      long a = strtol(p, &q, 10); 
      if (p == q) { 
       break; 
      } else { 
       sum += a; 
       p = q; 
      } 
     } 
     printf("sum = %ld\n", sum); 
    } 
    return 0; 
} 
+0

Где вы работаете с операторами? –

+0

@ YvesDaoust: Я поддерживаю только '+' и '-': удаление пробелов преобразует выражение в последовательность чисел, каждая из которых предшествует знаку' + 'или' -'. преобразование каждого числа с помощью 'strtol()' дает положительное или отрицательное значение и обновляет 'q', чтобы указать на следующий номер. Добавление разборного числа к сумме - все, что необходимо. Для поддержки большего числа операторов требуется более сложный метод со стеком или рекурсией. – chqrlie

+0

Извините, я пропустил, что 'strtol' обрабатывает знаки. –

0

Глядя этот код я вижу ошибку, после atoi() вы должны увеличиваем индекс в зависимости от размера номера (например, «656» длиной 3 символа).
Даже после этого исправить этот алгоритм не так, потому что вы выполняете операцию слишком рано. Я имею в виду, в вашем примере, этот алгоритм вычислений -45 + 98 и не вычислять 656.
Кроме того S[i]=S[i+1]; бесполезно так .. Неправильно

+0

Итак, как я на самом деле это делаю? Я имею в виду, как я могу добавить все эти числа, не зная, как долго это число? – manish

+0

Простой способ использовать это: 'sz = sprintf (tmp,"% d ", a);' –

1

Это (необычное) решение должно сделать трюк. Он работает строго слева направо:

sum= 0 
number= 0 
op= '+' 
while get(character) 
    case character of 
    digit: case op of 
      '+': sum-= number; number= 10 * number + character; sum+= number 
      '-': sum+= number; number= 10 * number + character; sum-= number 
    '+', '-': number= 0; op= character 

А теперь немного запутанном, но очень эффективный перевод C:

char* c= "45 - 98 + 656"; 
int s= 0, n= 0, d, p= 1; 
for (; d= *c - '0', *c; c++) 
    if ((unsigned)d <= 9) { s-= n; n= 10 * n + p * d; s+= n; } 
    else if (*c != ' ') { n= 0; p= *c == '+' ? 1 : -1; } 
printf("s = %d\n", s); 

Печатает 603, как и должно быть.

+1

Очень * необычный * Код на самом деле;) – chqrlie

+0

Достойный кандидат на [код гольфа] (http://codegolf.stackexchange.com) – chux