1

Есть переменная типа string, в неё записывается строка, введённая пользователем с клавиатуры. Нужно посчитать сумму всех цифр в этой строке.

Проблема в том, что не удаётся перевести символьную цифру в цифровую цифру. Пробовал юзать функцию atoi, но она выдаёт неправильный результат.

Мой код:

string s;
//code code...
cin>>s;
//code code...
for(int i=0;i<s.length();i++)
{
    cout<<s[i]<<" ";
    if((int)s[i]>47 && (int)s[i]<58)
    {
        count++;
        sum+=atoi(&s[i]);
    }
}
angry
  • 8,677
  • 18
  • 74
  • 182
Comfmore
  • 699
  • 1
    Ваш код с atoi() приведите, пожалуйста. – BuilderC Nov 05 '11 at 19:59
  • 1
    Для перевода десятичной цифры из символьного представления в двоичное просто вычтите из ее символьного представления символ '0'. – avp Nov 05 '11 at 20:47

5 Answers5

4

А еще навскидку, для обучения:

int summ = 0;
for (int i=0; i < myString.length(); ++i) {
    char c = myString[i];
    summ += c - '0';
}

Правда для уверенного использования понадобится проверочку добавить. Хотя она у вас и так уже сделана:

string s;
//code code...
cin>>s;
//code code...
for(int i=0;i<s.length();i++)
{
    cout<<s[i]<<" ";
    if((int)s[i]>47 && (int)s[i]<58)
    {
        sum += s[i] - '0';
    }
}
Dex
  • 9,981
  • 3
  • 34
  • 60
  • А почему без - '0' не работает? Чем мешает 0? – Comfmore Nov 05 '11 at 20:18
  • Так как за переменной типа char в общем случае сокрыт код символа (в вашем случае это коды от 48 - '0' и 57 - '9', чтобы простейшим способом перевести из char в реальное число, нужно от исходного кода отнять код нуля, что мы собственно и сделали. – Dex Nov 05 '11 at 20:24
  • Аа, вот оно что, хитро ) – Comfmore Nov 05 '11 at 20:28
  • Подозреваю, что за функцией atoi сей алгоритм и спрятан. – Dex Nov 05 '11 at 20:29
  • 2
    Все правильно. Для проверки, является ли символ цифрой, можно (и хорошо) воспользоваться функцией isdigit() из cctypes. – skegg Nov 05 '11 at 21:00
  • isdigit() - куда уж тривиальней)) Можно, конечно, и так, как написано. Это не будет ошибкой, естественно, и все будет работать. Но использование стандартной функции сделает код более... читабельным, что ли. Да и как-то это культурно - использовать стандартные функции. Дело функции. Я предложил лишь как вариант. – skegg Nov 05 '11 at 21:07
  • @mikillskegg, я ни в коем случае не осуждаю, вы не подумайте. Просто дополнительную библиотеку ради одной функции, не перебор ли? – Dex Nov 05 '11 at 21:11
  • Вообще-то эта функция содержится в libc, которая подключается к любой программе на C/С++. А заголовки далеко не всегда идут по принципу "один заголовок - одна библиотека"... – skegg Nov 05 '11 at 21:14
  • 2
    "Подозреваю, что за функцией atoi сей алгоритм и спрятан."

    atoi() ищет начало числа (пропускает "пробелы"), учитывает знак и останавливается по первой же не цифре, а также перед сложением умножает уже накопленную сумму на 10. А в остальном похоже.

    – avp Nov 05 '11 at 21:15
  • 1
    @mikillskegg, спасибо за разъяснения, я в С не особенно разбираюсь, с библиотеками мало знаком. – Dex Nov 05 '11 at 21:22
  • @skegg: стоит заметить, что легко можно ошибиться при вызове isdigit(). '0'..'9' гарантированно подряд идут, но я не помню, что численные значения конкретные в стандарте гарантированны. – jfs Oct 08 '17 at 04:08
3

Atoi преобразовывает строку в число. А символ - это не строка. Код будет например таким:

...
int summ = 0; //переменная в которой будет сумма всех цифр
int i = 0;
for (; i < myString.length(); ++i)
{
    char buff[2]; //массив который будет хранить один символ
    buff[0] = myString[i];
    buff[1] = '\0' //символ конца строки
    summ += atoi(buff);
}
...
Jakeroid
  • 1,444
  • 2
  • 22
  • 49
  • но работает и без строчки buff[1] = '\0' , зачем она нужна? – Comfmore Nov 05 '11 at 20:13
  • 2
    atoi() берет строку, а строка должна завершаться двоичным нулем.

    У Вас "и без строчки buff[1] = '\0'" работало только потому, что он (двоичный ноль) там случайно оказался.

    – avp Nov 05 '11 at 20:44
  • 1
    Можно, конечно, и так. Только как-то громоздко получилось. – skegg Nov 05 '11 at 21:15
  • Да, правильный (с учетом комментариев) ответ дал @Dex. Похоже, автор вопроса его не понял. Я объяснял насчет конца строки. – avp Nov 05 '11 at 21:20
3

В общем, подводя итог предложениям предыдущих авторов, предлагаю такой код

#include <iostream>
#include <cctype>
using namespace std;

int strsum (const string & str ) { int sum = 0, len = str.length(); for (int i = 0; i < len; i++) if (isdigit(str[i])) sum += str[i] - '0';
return sum; }

int main() { string st; cin >> st; cout << strsum (st) << endl; return 0; }

skegg
  • 23,934
  • 2
  • 38
  • 69
1

Еще так можно (ideone):

string s = "12345";
transform(s.begin(), s.end(), s.begin(), [](char c){return c-'0';});
int sum = accumulate(s.begin(), s.end(), 0);
cout << sum << endl;

но это только на тот случай, если все символы - цифры.

pank
  • 2,548
0

здесь, вроде тот-же вопрос обсуждается...
вот

/*-----------------------------------------------------------*/
//вот мой вариант(только для char)
#include<iostream>
using namespace std;
int conv(char c){
return c-'0';
}
//для конвертации string'a предлагаю использовать перегрузку для вводимого типа
//после чего возвращаемый результат посимвольно конвертируется и добваляется к 
//возвращаемому результату.
sudo97
  • 1,823
  • Кажись, там другое немного обсуждается. – skegg Nov 07 '11 at 11:41
  • 1
    Там нужно сосчитать сумму ЦИФР, которые находятся в строке, т.е. все остальные символы нужно игнорировать => делать проверку каждого символа, цифра ли это. – skegg Nov 07 '11 at 12:12